geocoder 1.1.9 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +309 -0
- data/LICENSE +1 -1
- data/README.md +544 -540
- data/bin/console +13 -0
- data/examples/app_defined_lookup_services.rb +22 -0
- data/examples/reverse_geocode_job.rb +40 -0
- data/lib/easting_northing.rb +171 -0
- data/lib/generators/geocoder/config/templates/initializer.rb +22 -16
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
- data/lib/generators/geocoder/migration_version.rb +15 -0
- data/lib/geocoder/cache.rb +20 -32
- data/lib/geocoder/cache_stores/base.rb +40 -0
- data/lib/geocoder/cache_stores/generic.rb +35 -0
- data/lib/geocoder/cache_stores/redis.rb +34 -0
- data/lib/geocoder/calculations.rb +67 -36
- data/lib/geocoder/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +33 -16
- data/lib/geocoder/configuration_hash.rb +4 -4
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/exceptions.rb +19 -0
- data/lib/geocoder/ip_address.rb +33 -0
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +74 -11
- data/lib/geocoder/lookups/abstract_api.rb +46 -0
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/amazon_location_service.rb +54 -0
- data/lib/geocoder/lookups/baidu.rb +24 -15
- data/lib/geocoder/lookups/baidu_ip.rb +30 -0
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
- data/lib/geocoder/lookups/base.rb +109 -23
- data/lib/geocoder/lookups/bing.rb +45 -10
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +4 -2
- data/lib/geocoder/lookups/esri.rb +61 -8
- data/lib/geocoder/lookups/freegeoip.rb +25 -6
- data/lib/geocoder/lookups/geoapify.rb +72 -0
- data/lib/geocoder/lookups/geocoder_ca.rb +5 -6
- data/lib/geocoder/lookups/geocodio.rb +42 -0
- data/lib/geocoder/lookups/geoip2.rb +49 -0
- data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/lib/geocoder/lookups/google.rb +45 -12
- data/lib/geocoder/lookups/google_places_details.rb +64 -0
- data/lib/geocoder/lookups/google_places_search.rb +76 -0
- data/lib/geocoder/lookups/google_premier.rb +16 -2
- data/lib/geocoder/lookups/here.rb +73 -0
- data/lib/geocoder/lookups/ip2location.rb +71 -0
- data/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/lib/geocoder/lookups/ipqualityscore.rb +50 -0
- data/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +58 -0
- data/lib/geocoder/lookups/location_iq.rb +54 -0
- data/lib/geocoder/lookups/mapbox.rb +59 -0
- data/lib/geocoder/lookups/mapquest.rb +9 -10
- data/lib/geocoder/lookups/maxmind.rb +10 -8
- data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/lib/geocoder/lookups/maxmind_local.rb +71 -0
- data/lib/geocoder/lookups/melissa_street.rb +41 -0
- data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/lib/geocoder/lookups/nominatim.rb +26 -6
- data/lib/geocoder/lookups/opencagedata.rb +65 -0
- data/lib/geocoder/lookups/osmnames.rb +57 -0
- data/lib/geocoder/lookups/pelias.rb +63 -0
- data/lib/geocoder/lookups/photon.rb +89 -0
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +69 -0
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +68 -0
- data/lib/geocoder/lookups/telize.rb +75 -0
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/test.rb +4 -0
- data/lib/geocoder/lookups/twogis.rb +58 -0
- data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/lookups/yandex.rb +18 -11
- data/lib/geocoder/models/active_record.rb +9 -4
- data/lib/geocoder/models/base.rb +1 -4
- data/lib/geocoder/models/mongo_base.rb +6 -4
- data/lib/geocoder/query.rb +23 -5
- data/lib/geocoder/railtie.rb +2 -2
- data/lib/geocoder/request.rb +102 -11
- data/lib/geocoder/results/abstract_api.rb +146 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/amazon_location_service.rb +57 -0
- data/lib/geocoder/results/baidu.rb +10 -14
- data/lib/geocoder/results/baidu_ip.rb +62 -0
- data/lib/geocoder/results/ban_data_gouv_fr.rb +282 -0
- data/lib/geocoder/results/base.rb +13 -1
- data/lib/geocoder/results/bing.rb +5 -1
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/esri.rb +35 -8
- data/lib/geocoder/results/freegeoip.rb +2 -7
- data/lib/geocoder/results/geoapify.rb +179 -0
- data/lib/geocoder/results/geocoder_ca.rb +3 -3
- data/lib/geocoder/results/geocodio.rb +78 -0
- data/lib/geocoder/results/geoip2.rb +76 -0
- data/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/lib/geocoder/results/google.rb +26 -0
- data/lib/geocoder/results/google_places_details.rb +39 -0
- data/lib/geocoder/results/google_places_search.rb +52 -0
- data/lib/geocoder/results/here.rb +77 -0
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/lib/geocoder/results/ipqualityscore.rb +54 -0
- data/lib/geocoder/results/ipregistry.rb +304 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/latlon.rb +71 -0
- data/lib/geocoder/results/location_iq.rb +6 -0
- data/lib/geocoder/results/mapbox.rb +63 -0
- data/lib/geocoder/results/mapquest.rb +5 -8
- data/lib/geocoder/results/maxmind.rb +0 -5
- data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/lib/geocoder/results/maxmind_local.rb +44 -0
- data/lib/geocoder/results/melissa_street.rb +46 -0
- data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/lib/geocoder/results/nominatim.rb +41 -14
- data/lib/geocoder/results/opencagedata.rb +100 -0
- data/lib/geocoder/results/osmnames.rb +56 -0
- data/lib/geocoder/results/pelias.rb +58 -0
- data/lib/geocoder/results/photon.rb +119 -0
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/pointpin.rb +40 -0
- data/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +142 -0
- data/lib/geocoder/results/telize.rb +40 -0
- data/lib/geocoder/results/tencent.rb +72 -0
- data/lib/geocoder/results/test.rb +20 -3
- data/lib/geocoder/results/twogis.rb +76 -0
- data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/results/yandex.rb +244 -32
- data/lib/geocoder/sql.rb +25 -21
- data/lib/geocoder/stores/active_record.rb +82 -26
- data/lib/geocoder/stores/base.rb +9 -14
- data/lib/geocoder/stores/mongo_base.rb +0 -31
- data/lib/geocoder/util.rb +29 -0
- data/lib/geocoder/version.rb +1 -1
- data/lib/geocoder.rb +6 -13
- data/lib/maxmind_database.rb +109 -0
- data/lib/tasks/geocoder.rake +30 -3
- data/lib/tasks/maxmind.rake +73 -0
- metadata +115 -98
- data/.gitignore +0 -5
- data/.travis.yml +0 -27
- data/Rakefile +0 -25
- data/examples/autoexpire_cache_dalli.rb +0 -62
- data/examples/autoexpire_cache_redis.rb +0 -28
- data/gemfiles/Gemfile.mongoid-2.4.x +0 -15
- data/lib/geocoder/lookups/geocoder_us.rb +0 -39
- data/lib/geocoder/lookups/ovi.rb +0 -62
- data/lib/geocoder/lookups/yahoo.rb +0 -86
- data/lib/geocoder/results/geocoder_us.rb +0 -39
- data/lib/geocoder/results/ovi.rb +0 -62
- data/lib/geocoder/results/yahoo.rb +0 -55
- data/lib/hash_recursive_merge.rb +0 -74
- data/lib/oauth_util.rb +0 -112
- data/test/active_record_test.rb +0 -15
- data/test/cache_test.rb +0 -35
- data/test/calculations_test.rb +0 -211
- data/test/configuration_test.rb +0 -78
- data/test/custom_block_test.rb +0 -32
- data/test/error_handling_test.rb +0 -43
- data/test/fixtures/baidu_invalid_key +0 -1
- data/test/fixtures/baidu_no_results +0 -1
- data/test/fixtures/baidu_reverse +0 -1
- data/test/fixtures/baidu_shanghai_pearl_tower +0 -12
- data/test/fixtures/bing_invalid_key +0 -1
- data/test/fixtures/bing_madison_square_garden +0 -40
- data/test/fixtures/bing_no_results +0 -16
- data/test/fixtures/bing_reverse +0 -42
- data/test/fixtures/esri_madison_square_garden +0 -59
- data/test/fixtures/esri_no_results +0 -8
- data/test/fixtures/esri_reverse +0 -21
- data/test/fixtures/freegeoip_74_200_247_59 +0 -12
- data/test/fixtures/freegeoip_no_results +0 -1
- data/test/fixtures/geocoder_ca_madison_square_garden +0 -1
- data/test/fixtures/geocoder_ca_no_results +0 -1
- data/test/fixtures/geocoder_ca_reverse +0 -34
- data/test/fixtures/geocoder_us_madison_square_garden +0 -1
- data/test/fixtures/geocoder_us_no_results +0 -1
- data/test/fixtures/google_garbage +0 -456
- data/test/fixtures/google_madison_square_garden +0 -57
- data/test/fixtures/google_no_city_data +0 -44
- data/test/fixtures/google_no_locality +0 -51
- data/test/fixtures/google_no_results +0 -4
- data/test/fixtures/google_over_limit +0 -4
- data/test/fixtures/mapquest_error +0 -16
- data/test/fixtures/mapquest_invalid_api_key +0 -16
- data/test/fixtures/mapquest_invalid_request +0 -16
- data/test/fixtures/mapquest_madison_square_garden +0 -52
- data/test/fixtures/mapquest_no_results +0 -16
- data/test/fixtures/maxmind_24_24_24_21 +0 -1
- data/test/fixtures/maxmind_24_24_24_22 +0 -1
- data/test/fixtures/maxmind_24_24_24_23 +0 -1
- data/test/fixtures/maxmind_24_24_24_24 +0 -1
- data/test/fixtures/maxmind_74_200_247_59 +0 -1
- data/test/fixtures/maxmind_invalid_key +0 -1
- data/test/fixtures/maxmind_no_results +0 -1
- data/test/fixtures/nominatim_madison_square_garden +0 -150
- data/test/fixtures/nominatim_no_results +0 -1
- data/test/fixtures/ovi_madison_square_garden +0 -72
- data/test/fixtures/ovi_no_results +0 -8
- data/test/fixtures/yahoo_error +0 -1
- data/test/fixtures/yahoo_invalid_key +0 -2
- data/test/fixtures/yahoo_madison_square_garden +0 -52
- data/test/fixtures/yahoo_no_results +0 -10
- data/test/fixtures/yahoo_over_limit +0 -2
- data/test/fixtures/yandex_invalid_key +0 -1
- data/test/fixtures/yandex_kremlin +0 -48
- data/test/fixtures/yandex_no_city_and_town +0 -112
- data/test/fixtures/yandex_no_results +0 -16
- data/test/geocoder_test.rb +0 -59
- data/test/https_test.rb +0 -16
- data/test/integration/smoke_test.rb +0 -26
- data/test/lookup_test.rb +0 -117
- data/test/method_aliases_test.rb +0 -25
- data/test/mongoid_test.rb +0 -46
- data/test/mongoid_test_helper.rb +0 -43
- data/test/near_test.rb +0 -61
- data/test/oauth_util_test.rb +0 -30
- data/test/proxy_test.rb +0 -36
- data/test/query_test.rb +0 -52
- data/test/request_test.rb +0 -29
- data/test/result_test.rb +0 -42
- data/test/services_test.rb +0 -393
- data/test/test_helper.rb +0 -289
- data/test/test_mode_test.rb +0 -59
|
@@ -2,79 +2,291 @@ require 'geocoder/results/base'
|
|
|
2
2
|
|
|
3
3
|
module Geocoder::Result
|
|
4
4
|
class Yandex < Base
|
|
5
|
+
# Yandex result has difficult tree structure,
|
|
6
|
+
# and presence of some nodes depends on exact search case.
|
|
7
|
+
|
|
8
|
+
# Also Yandex lacks documentation about it.
|
|
9
|
+
# See https://tech.yandex.com/maps/doc/geocoder/desc/concepts/response_structure-docpage/
|
|
10
|
+
|
|
11
|
+
# Ultimatly, we need to find Locality and/or Thoroughfare data.
|
|
12
|
+
|
|
13
|
+
# It may resides on the top (ADDRESS_DETAILS) level.
|
|
14
|
+
# example: 'Baltic Sea'
|
|
15
|
+
# "AddressDetails": {
|
|
16
|
+
# "Locality": {
|
|
17
|
+
# "Premise": {
|
|
18
|
+
# "PremiseName": "Baltic Sea"
|
|
19
|
+
# }
|
|
20
|
+
# }
|
|
21
|
+
# }
|
|
22
|
+
|
|
23
|
+
ADDRESS_DETAILS = %w[
|
|
24
|
+
GeoObject metaDataProperty GeocoderMetaData
|
|
25
|
+
AddressDetails
|
|
26
|
+
].freeze
|
|
27
|
+
|
|
28
|
+
# On COUNTRY_LEVEL.
|
|
29
|
+
# example: 'Potomak'
|
|
30
|
+
# "AddressDetails": {
|
|
31
|
+
# "Country": {
|
|
32
|
+
# "AddressLine": "reka Potomak",
|
|
33
|
+
# "CountryNameCode": "US",
|
|
34
|
+
# "CountryName": "United States of America",
|
|
35
|
+
# "Locality": {
|
|
36
|
+
# "Premise": {
|
|
37
|
+
# "PremiseName": "reka Potomak"
|
|
38
|
+
# }
|
|
39
|
+
# }
|
|
40
|
+
# }
|
|
41
|
+
# }
|
|
42
|
+
|
|
43
|
+
COUNTRY_LEVEL = %w[
|
|
44
|
+
GeoObject metaDataProperty GeocoderMetaData
|
|
45
|
+
AddressDetails Country
|
|
46
|
+
].freeze
|
|
47
|
+
|
|
48
|
+
# On ADMIN_LEVEL (usually state or city)
|
|
49
|
+
# example: 'Moscow, Tverskaya'
|
|
50
|
+
# "AddressDetails": {
|
|
51
|
+
# "Country": {
|
|
52
|
+
# "AddressLine": "Moscow, Tverskaya Street",
|
|
53
|
+
# "CountryNameCode": "RU",
|
|
54
|
+
# "CountryName": "Russia",
|
|
55
|
+
# "AdministrativeArea": {
|
|
56
|
+
# "AdministrativeAreaName": "Moscow",
|
|
57
|
+
# "Locality": {
|
|
58
|
+
# "LocalityName": "Moscow",
|
|
59
|
+
# "Thoroughfare": {
|
|
60
|
+
# "ThoroughfareName": "Tverskaya Street"
|
|
61
|
+
# }
|
|
62
|
+
# }
|
|
63
|
+
# }
|
|
64
|
+
# }
|
|
65
|
+
# }
|
|
66
|
+
|
|
67
|
+
ADMIN_LEVEL = %w[
|
|
68
|
+
GeoObject metaDataProperty GeocoderMetaData
|
|
69
|
+
AddressDetails Country
|
|
70
|
+
AdministrativeArea
|
|
71
|
+
].freeze
|
|
72
|
+
|
|
73
|
+
# On SUBADMIN_LEVEL (may refer to urban district)
|
|
74
|
+
# example: 'Moscow Region, Krasnogorsk'
|
|
75
|
+
# "AddressDetails": {
|
|
76
|
+
# "Country": {
|
|
77
|
+
# "AddressLine": "Moscow Region, Krasnogorsk",
|
|
78
|
+
# "CountryNameCode": "RU",
|
|
79
|
+
# "CountryName": "Russia",
|
|
80
|
+
# "AdministrativeArea": {
|
|
81
|
+
# "AdministrativeAreaName": "Moscow Region",
|
|
82
|
+
# "SubAdministrativeArea": {
|
|
83
|
+
# "SubAdministrativeAreaName": "gorodskoy okrug Krasnogorsk",
|
|
84
|
+
# "Locality": {
|
|
85
|
+
# "LocalityName": "Krasnogorsk"
|
|
86
|
+
# }
|
|
87
|
+
# }
|
|
88
|
+
# }
|
|
89
|
+
# }
|
|
90
|
+
# }
|
|
91
|
+
|
|
92
|
+
SUBADMIN_LEVEL = %w[
|
|
93
|
+
GeoObject metaDataProperty GeocoderMetaData
|
|
94
|
+
AddressDetails Country
|
|
95
|
+
AdministrativeArea
|
|
96
|
+
SubAdministrativeArea
|
|
97
|
+
].freeze
|
|
98
|
+
|
|
99
|
+
# On DEPENDENT_LOCALITY_1 (may refer to district of city)
|
|
100
|
+
# example: 'Paris, Etienne Marcel'
|
|
101
|
+
# "AddressDetails": {
|
|
102
|
+
# "Country": {
|
|
103
|
+
# "AddressLine": "Île-de-France, Paris, 1er Arrondissement, Rue Étienne Marcel",
|
|
104
|
+
# "CountryNameCode": "FR",
|
|
105
|
+
# "CountryName": "France",
|
|
106
|
+
# "AdministrativeArea": {
|
|
107
|
+
# "AdministrativeAreaName": "Île-de-France",
|
|
108
|
+
# "Locality": {
|
|
109
|
+
# "LocalityName": "Paris",
|
|
110
|
+
# "DependentLocality": {
|
|
111
|
+
# "DependentLocalityName": "1er Arrondissement",
|
|
112
|
+
# "Thoroughfare": {
|
|
113
|
+
# "ThoroughfareName": "Rue Étienne Marcel"
|
|
114
|
+
# }
|
|
115
|
+
# }
|
|
116
|
+
# }
|
|
117
|
+
# }
|
|
118
|
+
# }
|
|
119
|
+
# }
|
|
120
|
+
|
|
121
|
+
DEPENDENT_LOCALITY_1 = %w[
|
|
122
|
+
GeoObject metaDataProperty GeocoderMetaData
|
|
123
|
+
AddressDetails Country
|
|
124
|
+
AdministrativeArea Locality
|
|
125
|
+
DependentLocality
|
|
126
|
+
].freeze
|
|
127
|
+
|
|
128
|
+
# On DEPENDENT_LOCALITY_2 (for special cases like turkish "mahalle")
|
|
129
|
+
# https://en.wikipedia.org/wiki/Mahalle
|
|
130
|
+
# example: 'Istanbul Mabeyinci Yokuşu 17'
|
|
131
|
+
|
|
132
|
+
# "AddressDetails": {
|
|
133
|
+
# "Country": {
|
|
134
|
+
# "AddressLine": "İstanbul, Fatih, Saraç İshak Mah., Mabeyinci Yokuşu, 17",
|
|
135
|
+
# "CountryNameCode": "TR",
|
|
136
|
+
# "CountryName": "Turkey",
|
|
137
|
+
# "AdministrativeArea": {
|
|
138
|
+
# "AdministrativeAreaName": "İstanbul",
|
|
139
|
+
# "SubAdministrativeArea": {
|
|
140
|
+
# "SubAdministrativeAreaName": "Fatih",
|
|
141
|
+
# "Locality": {
|
|
142
|
+
# "DependentLocality": {
|
|
143
|
+
# "DependentLocalityName": "Saraç İshak Mah.",
|
|
144
|
+
# "Thoroughfare": {
|
|
145
|
+
# "ThoroughfareName": "Mabeyinci Yokuşu",
|
|
146
|
+
# "Premise": {
|
|
147
|
+
# "PremiseNumber": "17"
|
|
148
|
+
# }
|
|
149
|
+
# }
|
|
150
|
+
# }
|
|
151
|
+
# }
|
|
152
|
+
# }
|
|
153
|
+
# }
|
|
154
|
+
# }
|
|
155
|
+
# }
|
|
156
|
+
|
|
157
|
+
DEPENDENT_LOCALITY_2 = %w[
|
|
158
|
+
GeoObject metaDataProperty GeocoderMetaData
|
|
159
|
+
AddressDetails Country
|
|
160
|
+
AdministrativeArea
|
|
161
|
+
SubAdministrativeArea Locality
|
|
162
|
+
DependentLocality
|
|
163
|
+
].freeze
|
|
5
164
|
|
|
6
165
|
def coordinates
|
|
7
166
|
@data['GeoObject']['Point']['pos'].split(' ').reverse.map(&:to_f)
|
|
8
167
|
end
|
|
9
168
|
|
|
10
|
-
def address(
|
|
169
|
+
def address(_format = :full)
|
|
11
170
|
@data['GeoObject']['metaDataProperty']['GeocoderMetaData']['text']
|
|
12
171
|
end
|
|
13
172
|
|
|
14
173
|
def city
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
174
|
+
result =
|
|
175
|
+
if state.empty?
|
|
176
|
+
find_in_hash(@data, *COUNTRY_LEVEL, 'Locality', 'LocalityName')
|
|
177
|
+
elsif sub_state.empty?
|
|
178
|
+
find_in_hash(@data, *ADMIN_LEVEL, 'Locality', 'LocalityName')
|
|
179
|
+
else
|
|
180
|
+
find_in_hash(@data, *SUBADMIN_LEVEL, 'Locality', 'LocalityName')
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
result || ""
|
|
24
184
|
end
|
|
25
185
|
|
|
26
186
|
def country
|
|
27
|
-
|
|
187
|
+
find_in_hash(@data, *COUNTRY_LEVEL, 'CountryName') || ""
|
|
28
188
|
end
|
|
29
189
|
|
|
30
190
|
def country_code
|
|
31
|
-
|
|
191
|
+
find_in_hash(@data, *COUNTRY_LEVEL, 'CountryNameCode') || ""
|
|
32
192
|
end
|
|
33
193
|
|
|
34
194
|
def state
|
|
35
|
-
|
|
36
|
-
address_details['AdministrativeArea']['AdministrativeAreaName']
|
|
37
|
-
else
|
|
38
|
-
""
|
|
39
|
-
end
|
|
195
|
+
find_in_hash(@data, *ADMIN_LEVEL, 'AdministrativeAreaName') || ""
|
|
40
196
|
end
|
|
41
197
|
|
|
42
198
|
def sub_state
|
|
43
|
-
if
|
|
44
|
-
|
|
45
|
-
else
|
|
46
|
-
""
|
|
47
|
-
end
|
|
199
|
+
return "" if state.empty?
|
|
200
|
+
find_in_hash(@data, *SUBADMIN_LEVEL, 'SubAdministrativeAreaName') || ""
|
|
48
201
|
end
|
|
49
202
|
|
|
50
203
|
def state_code
|
|
51
204
|
""
|
|
52
205
|
end
|
|
53
206
|
|
|
54
|
-
def
|
|
55
|
-
""
|
|
207
|
+
def street
|
|
208
|
+
thoroughfare_data.is_a?(Hash) ? thoroughfare_data['ThoroughfareName'] : ""
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def street_number
|
|
212
|
+
premise.is_a?(Hash) ? premise.fetch('PremiseNumber', "") : ""
|
|
56
213
|
end
|
|
57
214
|
|
|
58
215
|
def premise_name
|
|
59
|
-
|
|
216
|
+
premise.is_a?(Hash) ? premise.fetch('PremiseName', "") : ""
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def postal_code
|
|
220
|
+
return "" unless premise.is_a?(Hash)
|
|
221
|
+
find_in_hash(premise, 'PostalCode', 'PostalCodeNumber') || ""
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def kind
|
|
225
|
+
@data['GeoObject']['metaDataProperty']['GeocoderMetaData']['kind']
|
|
60
226
|
end
|
|
61
227
|
|
|
62
228
|
def precision
|
|
63
229
|
@data['GeoObject']['metaDataProperty']['GeocoderMetaData']['precision']
|
|
64
230
|
end
|
|
65
231
|
|
|
232
|
+
def viewport
|
|
233
|
+
envelope = @data['GeoObject']['boundedBy']['Envelope'] || fail
|
|
234
|
+
east, north = envelope['upperCorner'].split(' ').map(&:to_f)
|
|
235
|
+
west, south = envelope['lowerCorner'].split(' ').map(&:to_f)
|
|
236
|
+
[south, west, north, east]
|
|
237
|
+
end
|
|
238
|
+
|
|
66
239
|
private # ----------------------------------------------------------------
|
|
67
240
|
|
|
68
|
-
def
|
|
69
|
-
@data
|
|
241
|
+
def top_level_locality
|
|
242
|
+
find_in_hash(@data, *ADDRESS_DETAILS, 'Locality')
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def country_level_locality
|
|
246
|
+
find_in_hash(@data, *COUNTRY_LEVEL, 'Locality')
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def admin_locality
|
|
250
|
+
find_in_hash(@data, *ADMIN_LEVEL, 'Locality')
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def subadmin_locality
|
|
254
|
+
find_in_hash(@data, *SUBADMIN_LEVEL, 'Locality')
|
|
70
255
|
end
|
|
71
256
|
|
|
72
|
-
def
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
257
|
+
def dependent_locality
|
|
258
|
+
find_in_hash(@data, *DEPENDENT_LOCALITY_1) ||
|
|
259
|
+
find_in_hash(@data, *DEPENDENT_LOCALITY_2)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def locality_data
|
|
263
|
+
dependent_locality || subadmin_locality || admin_locality ||
|
|
264
|
+
country_level_locality || top_level_locality
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def thoroughfare_data
|
|
268
|
+
locality_data['Thoroughfare'] if locality_data.is_a?(Hash)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def premise
|
|
272
|
+
if thoroughfare_data.is_a?(Hash)
|
|
273
|
+
thoroughfare_data['Premise']
|
|
274
|
+
elsif locality_data.is_a?(Hash)
|
|
275
|
+
locality_data['Premise']
|
|
77
276
|
end
|
|
78
277
|
end
|
|
278
|
+
|
|
279
|
+
def find_in_hash(source, *keys)
|
|
280
|
+
key = keys.shift
|
|
281
|
+
result = source[key]
|
|
282
|
+
|
|
283
|
+
if keys.empty?
|
|
284
|
+
return result
|
|
285
|
+
elsif !result.is_a?(Hash)
|
|
286
|
+
return nil
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
find_in_hash(result, *keys)
|
|
290
|
+
end
|
|
79
291
|
end
|
|
80
292
|
end
|
data/lib/geocoder/sql.rb
CHANGED
|
@@ -4,8 +4,8 @@ module Geocoder
|
|
|
4
4
|
|
|
5
5
|
##
|
|
6
6
|
# Distance calculation for use with a database that supports POWER(),
|
|
7
|
-
# SQRT(), PI(), and trigonometric functions SIN(), COS(), ASIN(),
|
|
8
|
-
# ATAN2()
|
|
7
|
+
# SQRT(), PI(), and trigonometric functions SIN(), COS(), ASIN(),
|
|
8
|
+
# ATAN2().
|
|
9
9
|
#
|
|
10
10
|
# Based on the excellent tutorial at:
|
|
11
11
|
# http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
|
|
@@ -44,13 +44,13 @@ module Geocoder
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def within_bounding_box(sw_lat, sw_lng, ne_lat, ne_lng, lat_attr, lon_attr)
|
|
47
|
-
spans = "#{lat_attr} BETWEEN #{sw_lat} AND #{ne_lat} AND "
|
|
47
|
+
spans = "#{lat_attr} BETWEEN #{sw_lat.to_f} AND #{ne_lat.to_f} AND "
|
|
48
48
|
# handle box that spans 180 longitude
|
|
49
49
|
if sw_lng.to_f > ne_lng.to_f
|
|
50
|
-
spans + "#{lon_attr} BETWEEN #{sw_lng} AND 180 OR " +
|
|
51
|
-
"#{lon_attr} BETWEEN -180 AND #{ne_lng}"
|
|
50
|
+
spans + "(#{lon_attr} BETWEEN #{sw_lng.to_f} AND 180 OR " +
|
|
51
|
+
"#{lon_attr} BETWEEN -180 AND #{ne_lng.to_f})"
|
|
52
52
|
else
|
|
53
|
-
spans + "#{lon_attr} BETWEEN #{sw_lng} AND #{ne_lng}"
|
|
53
|
+
spans + "#{lon_attr} BETWEEN #{sw_lng.to_f} AND #{ne_lng.to_f}"
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -59,30 +59,34 @@ module Geocoder
|
|
|
59
59
|
# and an options hash which must include a :bearing value
|
|
60
60
|
# (:linear or :spherical).
|
|
61
61
|
#
|
|
62
|
+
# For use with a database that supports MOD() and trigonometric functions
|
|
63
|
+
# SIN(), COS(), ASIN(), ATAN2().
|
|
64
|
+
#
|
|
62
65
|
# Based on:
|
|
63
66
|
# http://www.beginningspatial.com/calculating_bearing_one_point_another
|
|
64
67
|
#
|
|
65
68
|
def full_bearing(latitude, longitude, lat_attr, lon_attr, options = {})
|
|
69
|
+
degrees_per_radian = Geocoder::Calculations::DEGREES_PER_RADIAN
|
|
66
70
|
case options[:bearing] || Geocoder.config.distances
|
|
67
71
|
when :linear
|
|
68
|
-
"CAST(" +
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
")) + 360 " +
|
|
73
|
-
"AS decimal)
|
|
72
|
+
"MOD(CAST(" +
|
|
73
|
+
"(ATAN2( " +
|
|
74
|
+
"((#{lon_attr} - #{longitude.to_f}) / #{degrees_per_radian}), " +
|
|
75
|
+
"((#{lat_attr} - #{latitude.to_f}) / #{degrees_per_radian})" +
|
|
76
|
+
") * #{degrees_per_radian}) + 360 " +
|
|
77
|
+
"AS decimal), 360)"
|
|
74
78
|
when :spherical
|
|
75
|
-
"CAST(" +
|
|
76
|
-
"
|
|
77
|
-
"SIN(
|
|
78
|
-
"COS(
|
|
79
|
-
"COS(
|
|
79
|
+
"MOD(CAST(" +
|
|
80
|
+
"(ATAN2( " +
|
|
81
|
+
"SIN( (#{lon_attr} - #{longitude.to_f}) / #{degrees_per_radian} ) * " +
|
|
82
|
+
"COS( (#{lat_attr}) / #{degrees_per_radian} ), (" +
|
|
83
|
+
"COS( (#{latitude.to_f}) / #{degrees_per_radian} ) * SIN( (#{lat_attr}) / #{degrees_per_radian})" +
|
|
80
84
|
") - (" +
|
|
81
|
-
"SIN(
|
|
82
|
-
"COS(
|
|
85
|
+
"SIN( (#{latitude.to_f}) / #{degrees_per_radian}) * COS((#{lat_attr}) / #{degrees_per_radian}) * " +
|
|
86
|
+
"COS( (#{lon_attr} - #{longitude.to_f}) / #{degrees_per_radian})" +
|
|
83
87
|
")" +
|
|
84
|
-
")) + 360 " +
|
|
85
|
-
"AS decimal)
|
|
88
|
+
") * #{degrees_per_radian}) + 360 " +
|
|
89
|
+
"AS decimal), 360)"
|
|
86
90
|
end
|
|
87
91
|
end
|
|
88
92
|
|
|
@@ -18,14 +18,19 @@ module Geocoder::Store
|
|
|
18
18
|
|
|
19
19
|
# scope: geocoded objects
|
|
20
20
|
scope :geocoded, lambda {
|
|
21
|
-
where("#{geocoder_options[:latitude]} IS NOT NULL " +
|
|
22
|
-
"AND #{geocoder_options[:longitude]} IS NOT NULL")
|
|
21
|
+
where("#{table_name}.#{geocoder_options[:latitude]} IS NOT NULL " +
|
|
22
|
+
"AND #{table_name}.#{geocoder_options[:longitude]} IS NOT NULL")
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
# scope: not-geocoded objects
|
|
26
26
|
scope :not_geocoded, lambda {
|
|
27
|
-
where("#{geocoder_options[:latitude]} IS NULL " +
|
|
28
|
-
"OR #{geocoder_options[:longitude]} IS NULL")
|
|
27
|
+
where("#{table_name}.#{geocoder_options[:latitude]} IS NULL " +
|
|
28
|
+
"OR #{table_name}.#{geocoder_options[:longitude]} IS NULL")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# scope: not-reverse geocoded objects
|
|
32
|
+
scope :not_reverse_geocoded, lambda {
|
|
33
|
+
where("#{table_name}.#{geocoder_options[:fetched_address]} IS NULL")
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
##
|
|
@@ -45,7 +50,7 @@ module Geocoder::Store
|
|
|
45
50
|
# If no lat/lon given we don't want any results, but we still
|
|
46
51
|
# need distance and bearing columns so you can add, for example:
|
|
47
52
|
# .order("distance")
|
|
48
|
-
select(select_clause(nil,
|
|
53
|
+
select(select_clause(nil, null_value, null_value)).where(false_condition)
|
|
49
54
|
end
|
|
50
55
|
}
|
|
51
56
|
|
|
@@ -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(
|
|
@@ -64,7 +69,7 @@ module Geocoder::Store
|
|
|
64
69
|
full_column_name(geocoder_options[:longitude])
|
|
65
70
|
))
|
|
66
71
|
else
|
|
67
|
-
select(select_clause(nil,
|
|
72
|
+
select(select_clause(nil, null_value, null_value)).where(false_condition)
|
|
68
73
|
end
|
|
69
74
|
}
|
|
70
75
|
end
|
|
@@ -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.
|
|
@@ -107,31 +110,50 @@ module Geocoder::Store
|
|
|
107
110
|
# * +:exclude+ - an object to exclude (used by the +nearbys+ method)
|
|
108
111
|
# * +:distance_column+ - used to set the column name of the calculated distance.
|
|
109
112
|
# * +:bearing_column+ - used to set the column name of the calculated bearing.
|
|
113
|
+
# * +:min_radius+ - the value to use as the minimum radius.
|
|
114
|
+
# ignored if database is sqlite.
|
|
115
|
+
# default is 0.0
|
|
110
116
|
#
|
|
111
117
|
def near_scope_options(latitude, longitude, radius = 20, options = {})
|
|
112
118
|
if options[:units]
|
|
113
119
|
options[:units] = options[:units].to_sym
|
|
114
120
|
end
|
|
121
|
+
latitude_attribute = options[:latitude] || geocoder_options[:latitude]
|
|
122
|
+
longitude_attribute = options[:longitude] || geocoder_options[:longitude]
|
|
115
123
|
options[:units] ||= (geocoder_options[:units] || Geocoder.config.units)
|
|
116
|
-
select_distance = options.fetch(:select_distance
|
|
124
|
+
select_distance = options.fetch(:select_distance) { true }
|
|
117
125
|
options[:order] = "" if !select_distance && !options.include?(:order)
|
|
118
|
-
select_bearing = options.fetch(:select_bearing
|
|
126
|
+
select_bearing = options.fetch(:select_bearing) { true }
|
|
119
127
|
bearing = bearing_sql(latitude, longitude, options)
|
|
120
128
|
distance = distance_sql(latitude, longitude, options)
|
|
121
|
-
distance_column = options.fetch(:distance_column
|
|
122
|
-
bearing_column = options.fetch(:bearing_column
|
|
129
|
+
distance_column = options.fetch(:distance_column) { 'distance' }
|
|
130
|
+
bearing_column = options.fetch(:bearing_column) { 'bearing' }
|
|
123
131
|
|
|
124
|
-
|
|
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)
|
|
125
137
|
args = b + [
|
|
126
|
-
full_column_name(
|
|
127
|
-
full_column_name(
|
|
138
|
+
full_column_name(latitude_attribute),
|
|
139
|
+
full_column_name(longitude_attribute)
|
|
128
140
|
]
|
|
129
141
|
bounding_box_conditions = Geocoder::Sql.within_bounding_box(*args)
|
|
130
142
|
|
|
131
|
-
if
|
|
143
|
+
if using_unextended_sqlite?
|
|
132
144
|
conditions = bounding_box_conditions
|
|
133
145
|
else
|
|
134
|
-
|
|
146
|
+
min_radius = options.fetch(:min_radius, 0).to_f
|
|
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
|
|
135
157
|
end
|
|
136
158
|
{
|
|
137
159
|
:select => select_clause(options[:select],
|
|
@@ -149,12 +171,12 @@ module Geocoder::Store
|
|
|
149
171
|
# capabilities (trig functions?).
|
|
150
172
|
#
|
|
151
173
|
def distance_sql(latitude, longitude, options = {})
|
|
152
|
-
method_prefix =
|
|
174
|
+
method_prefix = using_unextended_sqlite? ? "approx" : "full"
|
|
153
175
|
Geocoder::Sql.send(
|
|
154
176
|
method_prefix + "_distance",
|
|
155
177
|
latitude, longitude,
|
|
156
|
-
full_column_name(geocoder_options[:latitude]),
|
|
157
|
-
full_column_name(geocoder_options[:longitude]),
|
|
178
|
+
full_column_name(options[:latitude] || geocoder_options[:latitude]),
|
|
179
|
+
full_column_name(options[:longitude]|| geocoder_options[:longitude]),
|
|
158
180
|
options
|
|
159
181
|
)
|
|
160
182
|
end
|
|
@@ -168,12 +190,12 @@ module Geocoder::Store
|
|
|
168
190
|
options[:bearing] = Geocoder.config.distances
|
|
169
191
|
end
|
|
170
192
|
if options[:bearing]
|
|
171
|
-
method_prefix =
|
|
193
|
+
method_prefix = using_unextended_sqlite? ? "approx" : "full"
|
|
172
194
|
Geocoder::Sql.send(
|
|
173
195
|
method_prefix + "_bearing",
|
|
174
196
|
latitude, longitude,
|
|
175
|
-
full_column_name(geocoder_options[:latitude]),
|
|
176
|
-
full_column_name(geocoder_options[:longitude]),
|
|
197
|
+
full_column_name(options[:latitude] || geocoder_options[:latitude]),
|
|
198
|
+
full_column_name(options[:longitude]|| geocoder_options[:longitude]),
|
|
177
199
|
options
|
|
178
200
|
)
|
|
179
201
|
end
|
|
@@ -214,15 +236,38 @@ module Geocoder::Store
|
|
|
214
236
|
conditions
|
|
215
237
|
end
|
|
216
238
|
|
|
239
|
+
def using_unextended_sqlite?
|
|
240
|
+
using_sqlite? && !using_sqlite_with_extensions?
|
|
241
|
+
end
|
|
242
|
+
|
|
217
243
|
def using_sqlite?
|
|
218
|
-
connection.adapter_name.match
|
|
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
|
+
}
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def using_postgres?
|
|
256
|
+
connection.adapter_name.match(/postgres/i)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
##
|
|
260
|
+
# Use OID type when running in PosgreSQL
|
|
261
|
+
#
|
|
262
|
+
def null_value
|
|
263
|
+
using_postgres? ? 'NULL::text' : 'NULL'
|
|
219
264
|
end
|
|
220
265
|
|
|
221
266
|
##
|
|
222
267
|
# Value which can be passed to where() to produce no results.
|
|
223
268
|
#
|
|
224
269
|
def false_condition
|
|
225
|
-
|
|
270
|
+
using_unextended_sqlite? ? 0 : "false"
|
|
226
271
|
end
|
|
227
272
|
|
|
228
273
|
##
|
|
@@ -234,6 +279,17 @@ module Geocoder::Store
|
|
|
234
279
|
end
|
|
235
280
|
end
|
|
236
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
|
+
|
|
237
293
|
##
|
|
238
294
|
# Look up coordinates and assign to +latitude+ and +longitude+ attributes
|
|
239
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,14 @@ module Geocoder
|
|
|
101
90
|
return
|
|
102
91
|
end
|
|
103
92
|
|
|
104
|
-
|
|
93
|
+
query_options = [:lookup, :ip_lookup, :language, :params].inject({}) do |hash, key|
|
|
94
|
+
if options.has_key?(key)
|
|
95
|
+
val = options[key]
|
|
96
|
+
hash[key] = val.respond_to?(:call) ? val.call(self) : val
|
|
97
|
+
end
|
|
98
|
+
hash
|
|
99
|
+
end
|
|
100
|
+
results = Geocoder.search(query, query_options)
|
|
105
101
|
|
|
106
102
|
# execute custom block, if specified in configuration
|
|
107
103
|
block_key = reverse ? :reverse_block : :geocode_block
|
|
@@ -117,4 +113,3 @@ module Geocoder
|
|
|
117
113
|
end
|
|
118
114
|
end
|
|
119
115
|
end
|
|
120
|
-
|