geocoder 1.2.3 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of geocoder might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29ab290c8d6f4d7604e92add7c07f37b47b9f7c1
4
- data.tar.gz: 6cbd84ac0eac3f768f68e69024232c3ab489ee48
3
+ metadata.gz: 6fbab97a77881d1d3e78e4016db9ed11c3592c96
4
+ data.tar.gz: e553d469d6d9e2148efdc12476c4a36d11f1096e
5
5
  SHA512:
6
- metadata.gz: 29cebb43ee5215ccf28154c5e8f41985f5079cc6f765fedfae222e17379ecad604977ec5fc92f1f5ba9dd17c7d26f60c96df9a6b8372eced7d5a7814dc4b1c0b
7
- data.tar.gz: 07e490262d72393456d1915dfb054b16448e454a6f14f1e910a21758547b73c6e03abd2dfa66a7b8966ec6758e91bd0ea3d1d00ee1a077b0202071ed59155acb
6
+ metadata.gz: 0f9e1bf14f86d2465efb15a9b2531bdc227cc7b5b73a096abb9510dcc4af83c36d28a718138b934f37b275b89b09f783610ea7990b92dd06db0493d90b2d35bd
7
+ data.tar.gz: 9e5e70a01776b4e2ab0baae341b8151dbc435ec20c3a5da7851b5c5f0c7df343d188a9092fe746c99ec653753cb9a9cd32d9c8aa22de02c95475bbc28f530ca2
data/CHANGELOG.md CHANGED
@@ -3,13 +3,19 @@ Changelog
3
3
 
4
4
  Major changes to Geocoder for each release. Please see the Git log for complete list of changes.
5
5
 
6
- 1.2.3 (2014 June 11)
6
+ 1.2.4 (2014 Aug 12)
7
+ -------------------
8
+ * Add ability to specify lat/lon column names with .near scope (thanks github.com/switzersc).
9
+ * Add OpenCageData geocoder (thanks github.com/mtmail).
10
+ * Remove CloudMade geocoder.
7
11
 
12
+ 1.2.3 (2014 Jul 11)
13
+ -------------------
8
14
  * Add Telize IP address lookup (thanks github.com/lukeroberts1990).
9
15
  * Fix bug in Bing reverse geocoding (thanks github.com/nickelser).
10
16
 
11
17
  1.2.2 (2014 Jun 12)
12
-
18
+ -------------------
13
19
  * Add ability to specify language per query (thanks github.com/mkristian).
14
20
  * Handle Errno::ECONNREFUSED exceptions like TimeoutError exceptions.
15
21
  * Switch to 'unstructured' query format for Bing API (thanks github.com/lukewendling).
data/README.md CHANGED
@@ -272,6 +272,10 @@ lower bound (ie. think of a donut, or ring) by using the `:min_radius` option:
272
272
 
273
273
  box = Geocoder::Calculations.bounding_box(center_point, distance, :min_radius => 10.5)
274
274
 
275
+ With ActiveRecord, you can specify alternate latitude and longitude column names for a geocoded model (useful if you store multiple sets of coordinates for each object):
276
+
277
+ Venue.near("Paris", 50, latitude: :secondary_latitude, longitude: :secondary_longitude)
278
+
275
279
 
276
280
  Advanced Geocoding
277
281
  ------------------
@@ -427,6 +431,17 @@ The following is a comparison of the supported geocoding APIs. The "Limitations"
427
431
  * **Terms of Service**: http://wiki.openstreetmap.org/wiki/Nominatim_usage_policy
428
432
  * **Limitations**: Please limit request rate to 1 per second and include your contact information in User-Agent headers (eg: `Geocoder.configure(:http_headers => { "User-Agent" => "your contact info" })`). Data licensed under CC-BY-SA (you must provide attribution).
429
433
 
434
+ #### OpenCageData (`:opencagedata`)
435
+
436
+ * **API key**: required
437
+ * **Key signup**: http://geocoder.opencagedata.com
438
+ * **Quota**: 2500 requests / day, then ability to purchase more (free during beta)
439
+ * **Region**: world
440
+ * **SSL support**: yes
441
+ * **Languages**: worldwide
442
+ * **Documentation**: http://geocoder.opencagedata.com/api.html
443
+ * **Limitations**: Data licensed under CC-BY-SA or (you must provide attribution).
444
+
430
445
  #### Yandex (`:yandex`)
431
446
 
432
447
  * **API key**: none
@@ -537,17 +552,6 @@ Data Science Toolkit provides an API whose reponse format is like Google's but w
537
552
  * **Limitations**: Only good for non-commercial use. For commercial usage please check http://developer.baidu.com/map/question.htm#qa0013
538
553
  * **Notes**: To use Baidu set `Geocoder.configure(:lookup => :baidu, :api_key => "your_api_key")`.
539
554
 
540
- #### CloudMade (`:cloudmade`)
541
-
542
- * **API key**: required
543
- * **Quota**: 100,000 free requests, then purchase 100,000 more for $15
544
- * **Region**: world
545
- * **SSL support**: yes ($5 per 100,000 requests)
546
- * **Languages**: en
547
- * **Documentation**: http://cloudmade.com/documentation/geocoding
548
- * **Terms of Service**: http://cloudmade.com/api-terms-of-service
549
- * **Limitations**: ?
550
-
551
555
  #### Geocodio (`:geocodio`)
552
556
 
553
557
  * **API key**: required
@@ -584,6 +588,18 @@ Data Science Toolkit provides an API whose reponse format is like Google's but w
584
588
  * **Limitations**: ?
585
589
  * **Notes**: If you are [running your own local instance of the FreeGeoIP service](https://github.com/fiorix/freegeoip) you can configure the host like this: `Geocoder.configure(freegeoip: {host: "..."})`.
586
590
 
591
+ #### Pointpin (`:pointpin`)
592
+
593
+ * **API key**: required
594
+ * **Quota**: 50,000/mo for €9 through 1m/mo for €49
595
+ * **Region**: world
596
+ * **SSL support**: yes
597
+ * **Languages**: English
598
+ * **Documentation**: https://pointp.in/docs/get-started
599
+ * **Terms of Service**: https://pointp.in/terms
600
+ * **Limitations**: ?
601
+ * **Notes**: To use Pointpin set `Geocoder.configure(:ip_lookup => :pointpin, :api_key => "your_pointpin_api_key")`.
602
+
587
603
  #### Telize (`:telize`)
588
604
 
589
605
  * **API key**: none
@@ -32,10 +32,10 @@ module Geocoder
32
32
  :yandex,
33
33
  :nominatim,
34
34
  :mapquest,
35
+ :opencagedata,
35
36
  :ovi,
36
37
  :here,
37
38
  :baidu,
38
- :cloudmade,
39
39
  :geocodio,
40
40
  :smarty_streets,
41
41
  :test
@@ -51,7 +51,8 @@ module Geocoder
51
51
  :freegeoip,
52
52
  :maxmind,
53
53
  :maxmind_local,
54
- :telize
54
+ :telize,
55
+ :pointpin
55
56
  ]
56
57
  end
57
58
 
@@ -99,7 +99,7 @@ module Geocoder
99
99
  # Object used to make HTTP requests.
100
100
  #
101
101
  def http_client
102
- protocol = "http#{'s' if configuration.use_https}"
102
+ protocol = "http#{'s' if use_ssl?}"
103
103
  proxy_name = "#{protocol}_proxy"
104
104
  if proxy = configuration.send(proxy_name)
105
105
  proxy_url = !!(proxy =~ /^#{protocol}/) ? proxy : protocol + '://' + proxy
@@ -198,7 +198,7 @@ module Geocoder
198
198
  # Set in configuration but not available for every service.
199
199
  #
200
200
  def protocol
201
- "http" + (configuration.use_https ? "s" : "")
201
+ "http" + (use_ssl? ? "s" : "")
202
202
  end
203
203
 
204
204
  def valid_response?(response)
@@ -249,6 +249,9 @@ module Geocoder
249
249
  elsif response.code.to_i == 402
250
250
  raise_error(Geocoder::OverQueryLimitError) ||
251
251
  warn("Geocoding API error: 402 Payment Required")
252
+ elsif response.code.to_i == 429
253
+ raise_error(Geocoder::OverQueryLimitError) ||
254
+ warn("Geocoding API error: 429 Too Many Requests")
252
255
  end
253
256
  end
254
257
 
@@ -262,7 +265,7 @@ module Geocoder
262
265
  args = [uri.host, uri.port]
263
266
  args = args.push(uri.user, uri.password) unless uri.user.nil? or uri.password.nil?
264
267
  opts = {}
265
- opts[:use_ssl] = true if configuration.use_https
268
+ opts[:use_ssl] = use_ssl?
266
269
 
267
270
  http_client.start(*args, opts) do |client|
268
271
  client.get(uri.request_uri, configuration.http_headers)
@@ -270,6 +273,10 @@ module Geocoder
270
273
  end
271
274
  end
272
275
 
276
+ def use_ssl?
277
+ configuration.use_https
278
+ end
279
+
273
280
  def check_api_key_configuration!(query)
274
281
  key_parts = query.lookup.required_api_key_parts
275
282
  if key_parts.size > Array(configuration.api_key).size
@@ -0,0 +1,58 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/opencagedata'
3
+
4
+ module Geocoder::Lookup
5
+ class Opencagedata < Base
6
+
7
+ def name
8
+ "OpenCageData"
9
+ end
10
+
11
+ def query_url(query)
12
+ "#{protocol}://api.opencagedata.com/geocode/v1/json?key=#{configuration.api_key}&q=#{url_query_string(query)}"
13
+ end
14
+
15
+ def required_api_key_parts
16
+ ["key"]
17
+ end
18
+
19
+ private
20
+
21
+ def results(query)
22
+ return [] unless doc = fetch_data(query)
23
+ # return doc["results"]
24
+
25
+ messages = doc['status']['message']
26
+ case doc['status']['code']
27
+ when 400 # Error with input
28
+ raise_error(Geocoder::InvalidRequest, messages) ||
29
+ warn("Opencagedata Geocoding API error: #{messages}")
30
+ when 403 # Key related error
31
+ raise_error(Geocoder::InvalidApiKey, messages) ||
32
+ warn("Opencagedata Geocoding API error: #{messages}")
33
+ when 402 # Quata Exceeded
34
+ raise_error(Geocoder::OverQueryLimitError, messages) ||
35
+ warn("Opencagedata Geocoding API error: #{messages}")
36
+ when 500 # Unknown error
37
+ raise_error(Geocoder::Error, messages) ||
38
+ warn("Opencagedata Geocoding API error: #{messages}")
39
+ end
40
+
41
+ return doc["results"]
42
+ end
43
+
44
+ def query_url_params(query)
45
+ params = {
46
+ :query => query.sanitized_text,
47
+ :language => (query.language || configuration.language)
48
+ }.merge(super)
49
+
50
+ unless (bounds = query.options[:bounds]).nil?
51
+ params[:bounds] = bounds.map{ |point| "%f,%f" % point }.join(',')
52
+ end
53
+
54
+ params
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,68 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/pointpin'
3
+
4
+ module Geocoder::Lookup
5
+ class Pointpin < Base
6
+
7
+ def name
8
+ "Pointpin"
9
+ end
10
+
11
+ def required_api_key_parts
12
+ ["key"]
13
+ end
14
+
15
+ def query_url(query)
16
+ "#{ protocol }://geo.pointp.in/#{ api_key }/json/#{ query.sanitized_text }"
17
+ end
18
+
19
+ private
20
+
21
+ def results(query)
22
+ # don't look up a loopback address, just return the stored result
23
+ return [] if query.loopback_ip_address?
24
+ doc = fetch_data(query)
25
+ if doc and doc.is_a?(Hash)
26
+ if !data_contains_error?(doc)
27
+ return [doc]
28
+ elsif doc['error']
29
+ case doc['error']
30
+ when "Invalid IP address"
31
+ raise_error(Geocoder::InvalidRequest) || warn("Invalid Pointpin request.")
32
+ when "Invalid API key"
33
+ raise_error(Geocoder::InvalidApiKey) || warn("Invalid Pointpin API key.")
34
+ when "Address not found"
35
+ warn("Address not found.")
36
+ end
37
+ else
38
+ raise_error(Geocoder::Error) || warn("Pointpin server error")
39
+ end
40
+ end
41
+
42
+ return []
43
+ end
44
+
45
+ def data_contains_error?(parsed_data)
46
+ parsed_data.keys.include?('error')
47
+ end
48
+
49
+ def reserved_result(ip)
50
+ {
51
+ "ip" => ip,
52
+ "city" => "",
53
+ "region_code" => "",
54
+ "region_name" => "",
55
+ "metrocode" => "",
56
+ "zipcode" => "",
57
+ "latitude" => "0",
58
+ "longitude" => "0",
59
+ "country_name" => "Reserved",
60
+ "country_code" => "RD"
61
+ }
62
+ end
63
+
64
+ def api_key
65
+ configuration.api_key
66
+ end
67
+ end
68
+ end
@@ -15,6 +15,10 @@ module Geocoder::Lookup
15
15
 
16
16
  private # ---------------------------------------------------------------
17
17
 
18
+ def use_ssl?
19
+ false
20
+ end
21
+
18
22
  def results(query)
19
23
  # don't look up a loopback address, just return the stored result
20
24
  return [reserved_result(query.text)] if query.loopback_ip_address?
@@ -45,7 +45,7 @@ module Geocoder::Result
45
45
  end
46
46
 
47
47
  def coordinates
48
- ['lat', 'lng'].map{ |i| location[i] } if location
48
+ ['lat', 'lng'].map{ |i| location[i].to_f } if location
49
49
  end
50
50
 
51
51
  def accuracy
@@ -0,0 +1,82 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Opencagedata < Base
5
+
6
+ def poi
7
+ %w[stadium bus_stop tram_stop].each do |key|
8
+ return @data['components'][key] if @data['components'].key?(key)
9
+ end
10
+ return nil
11
+ end
12
+
13
+ def house_number
14
+ @data['components']['house_number']
15
+ end
16
+
17
+ def address
18
+ @data['formatted']
19
+ end
20
+
21
+ def street
22
+ %w[road pedestrian highway].each do |key|
23
+ return @data['components'][key] if @data['components'].key?(key)
24
+ end
25
+ return nil
26
+ end
27
+
28
+ def city
29
+ %w[city town village hamlet].each do |key|
30
+ return @data['components'][key] if @data['components'].key?(key)
31
+ end
32
+ return nil
33
+ end
34
+
35
+ def village
36
+ @data['components']['village']
37
+ end
38
+
39
+
40
+ def state
41
+ @data['components']['state']
42
+ end
43
+
44
+ alias_method :state_code, :state
45
+
46
+ def postal_code
47
+ @data['components']['postcode'].to_s
48
+ end
49
+
50
+ def county
51
+ @data['components']['county']
52
+ end
53
+
54
+ def country
55
+ @data['components']['country']
56
+ end
57
+
58
+ def country_code
59
+ @data['components']['country_code']
60
+ end
61
+
62
+ def suburb
63
+ @data['components']['suburb']
64
+ end
65
+
66
+ def coordinates
67
+ [@data['lat'].to_f, @data['lon'].to_f]
68
+ end
69
+ def self.response_attributes
70
+ %w[boundingbox license
71
+ formatted stadium]
72
+ end
73
+
74
+ response_attributes.each do |a|
75
+ unless method_defined?(a)
76
+ define_method a do
77
+ @data[a]
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,44 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Pointpin < Base
5
+
6
+ def address
7
+ [ city_name, state, postal_code, country ].select{ |i| i.to_s != "" }.join(", ")
8
+ end
9
+
10
+ def city
11
+ @data['city_name']
12
+ end
13
+
14
+ def state
15
+ @data['region_name']
16
+ end
17
+
18
+ def state_code
19
+ @data['region_code']
20
+ end
21
+
22
+ def country
23
+ @data['country_name']
24
+ end
25
+
26
+ def country_code
27
+ @data['country_code']
28
+ end
29
+
30
+ def postal_code
31
+ @data['postcode']
32
+ end
33
+
34
+ def self.response_attributes
35
+ %w[continent_code ip country_code country_name region_name city_name postcode latitude longitude time_zone languages]
36
+ end
37
+
38
+ response_attributes.each do |a|
39
+ define_method a do
40
+ @data[a]
41
+ end
42
+ end
43
+ end
44
+ end
@@ -115,6 +115,8 @@ module Geocoder::Store
115
115
  if options[:units]
116
116
  options[:units] = options[:units].to_sym
117
117
  end
118
+ latitude_attribute = options[:latitude] || geocoder_options[:latitude]
119
+ longitude_attribute = options[:longitude] || geocoder_options[:longitude]
118
120
  options[:units] ||= (geocoder_options[:units] || Geocoder.config.units)
119
121
  select_distance = options.fetch(:select_distance, true)
120
122
  options[:order] = "" if !select_distance && !options.include?(:order)
@@ -126,8 +128,8 @@ module Geocoder::Store
126
128
 
127
129
  b = Geocoder::Calculations.bounding_box([latitude, longitude], radius, options)
128
130
  args = b + [
129
- full_column_name(geocoder_options[:latitude]),
130
- full_column_name(geocoder_options[:longitude])
131
+ full_column_name(latitude_attribute),
132
+ full_column_name(longitude_attribute)
131
133
  ]
132
134
  bounding_box_conditions = Geocoder::Sql.within_bounding_box(*args)
133
135
 
@@ -157,8 +159,8 @@ module Geocoder::Store
157
159
  Geocoder::Sql.send(
158
160
  method_prefix + "_distance",
159
161
  latitude, longitude,
160
- full_column_name(geocoder_options[:latitude]),
161
- full_column_name(geocoder_options[:longitude]),
162
+ full_column_name(options[:latitude] || geocoder_options[:latitude]),
163
+ full_column_name(options[:longitude]|| geocoder_options[:longitude]),
162
164
  options
163
165
  )
164
166
  end
@@ -176,8 +178,8 @@ module Geocoder::Store
176
178
  Geocoder::Sql.send(
177
179
  method_prefix + "_bearing",
178
180
  latitude, longitude,
179
- full_column_name(geocoder_options[:latitude]),
180
- full_column_name(geocoder_options[:longitude]),
181
+ full_column_name(options[:latitude] || geocoder_options[:latitude]),
182
+ full_column_name(options[:longitude]|| geocoder_options[:longitude]),
181
183
  options
182
184
  )
183
185
  end
@@ -1,3 +1,3 @@
1
1
  module Geocoder
2
- VERSION = "1.2.3"
2
+ VERSION = "1.2.4"
3
3
  end
@@ -1 +1 @@
1
- {"input":{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC"},"results":[{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC","zip":"20004"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC, 20004","location":{"lat":38.895019,"lng":-77.028095},"accuracy":1},{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC","zip":"20004"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC, 20004","location":{"lat":38.895016122449,"lng":-77.028084377551},"accuracy":0.8}]}
1
+ {"input":{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC"},"results":[{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC","zip":"20004"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC, 20004","location":{"lat":"38.895019","lng":"-77.028095"},"accuracy":1},{"address_components":{"number":"1101","street":"Pennsylvania","suffix":"Ave","postdirectional":"NW","city":"Washington","state":"DC","zip":"20004"},"formatted_address":"1101 Pennsylvania Ave NW, Washington DC, 20004","location":{"lat":"38.895016122449","lng":"-77.028084377551"},"accuracy":0.8}]}
@@ -0,0 +1,25 @@
1
+ {
2
+ "licenses": [
3
+ {
4
+ "name": "CC-BY-SA",
5
+ "url": "http://creativecommons.org/licenses/by-sa/3.0/"
6
+ },
7
+ {
8
+ "name": "ODbL",
9
+ "url": "http://opendatacommons.org/licenses/odbl/summary/"
10
+ }
11
+ ],
12
+ "results": [ ],
13
+ "status": {
14
+ "code": 403,
15
+ "message": "invalid API key"
16
+ },
17
+ "thanks": "For using an OpenCage Data API",
18
+ "timestamp": {
19
+ "created_http": "Thu, 07 Aug 2014 14:26:28 GMT",
20
+ "created_unix": 1407421588
21
+ },
22
+ "total_results": 0,
23
+ "we_are_hiring": "http://lokku.com/#jobs"
24
+
25
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+
3
+ "licenses": [
4
+ {
5
+ "name": "CC-BY-SA",
6
+ "url": "http://creativecommons.org/licenses/by-sa/3.0/"
7
+ },
8
+ {
9
+ "name": "ODbL",
10
+ "url": "http://opendatacommons.org/licenses/odbl/summary/"
11
+ }
12
+ ],
13
+ "results": [ ],
14
+ "status": {
15
+ "code": 400,
16
+ "message": "Attribute (format) does not pass the type constraint because: not a valid format"
17
+ },
18
+ "thanks": "For using an OpenCage Data API",
19
+ "timestamp": {
20
+ "created_http": "Thu, 07 Aug 2014 14:27:29 GMT",
21
+ "created_unix": 1407421649
22
+ },
23
+ "total_results": 0,
24
+ "we_are_hiring": "http://lokku.com/#jobs"
25
+
26
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "licenses" : [
3
+ {
4
+ "name" : "CC-BY-SA",
5
+ "url" : "http://creativecommons.org/licenses/by-sa/3.0/"
6
+ },
7
+ {
8
+ "name" : "ODbL",
9
+ "url" : "http://opendatacommons.org/licenses/odbl/summary/"
10
+ }
11
+ ],
12
+ "rate" : {
13
+ "limit" : 2500,
14
+ "remaining" : 2488,
15
+ "reset" : 1407369600
16
+ },
17
+ "results" : [
18
+ {
19
+ "annotations" : {
20
+ "OSM" : {
21
+ "url" : "http://www.openstreetmap.org/?mlat=40.75052&mlon=-73.99355#map=17/40.75052/-73.99355"
22
+ },
23
+ "timezone" : {
24
+ "name" : "America/New_York",
25
+ "now_in_dst" : 1,
26
+ "offset_sec" : -14400,
27
+ "offset_string" : -400,
28
+ "short_name" : "EDT"
29
+ }
30
+ },
31
+ "bounds" : {
32
+ "northeast" : {
33
+ "lat" : 40.751161,
34
+ "lng" : -73.9925922
35
+ },
36
+ "southwest" : {
37
+ "lat" : 40.7498531,
38
+ "lng" : -73.9944444
39
+ }
40
+ },
41
+ "components" : {
42
+ "country" : "United States of America",
43
+ "country_code" : "US",
44
+ "county" : "New York County",
45
+ "house_number" : 46,
46
+ "neighbourhood" : "Koreatown",
47
+ "postcode" : 10011,
48
+ "road" : "West 31st Street",
49
+ "city": "New York City",
50
+ "stadium" : "Madison Square Garden",
51
+ "state" : "New York",
52
+ "state_district" : "New York City"
53
+ },
54
+ "confidence" : 10,
55
+ "formatted" : "46, West 31st Street, Koreatown, New York County, 10011, New York City, New York, United States of America, Madison Square Garden",
56
+ "geometry" : {
57
+ "lat" : 40.7505247,
58
+ "lng" : -73.9935500942432
59
+ }
60
+ }
61
+ ],
62
+ "status" : {
63
+ "code" : 200,
64
+ "message" : "OK"
65
+ },
66
+ "thanks" : "For using an OpenCage Data API",
67
+ "timestamp" : {
68
+ "created_http" : "Wed, 06 Aug 2014 12:53:59 GMT",
69
+ "created_unix" : 1407329639
70
+ },
71
+ "total_results" : 1,
72
+ "we_are_hiring" : "http://lokku.com/#jobs"
73
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "licenses" : [
3
+ {
4
+ "name" : "CC-BY-SA",
5
+ "url" : "http://creativecommons.org/licenses/by-sa/3.0/"
6
+ },
7
+ {
8
+ "name" : "ODbL",
9
+ "url" : "http://opendatacommons.org/licenses/odbl/summary/"
10
+ }
11
+ ],
12
+ "rate" : {
13
+ "limit" : 2500,
14
+ "remaining" : 2487,
15
+ "reset" : 1407369600
16
+ },
17
+ "results" : [],
18
+ "status" : {
19
+ "code" : 200,
20
+ "message" : "OK"
21
+ },
22
+ "thanks" : "For using an OpenCage Data API",
23
+ "timestamp" : {
24
+ "created_http" : "Wed, 06 Aug 2014 12:56:03 GMT",
25
+ "created_unix" : 1407329763
26
+ },
27
+ "total_results" : 0,
28
+ "we_are_hiring" : "http://lokku.com/#jobs"
29
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+
3
+ "licenses": [
4
+ {
5
+ "name": "CC-BY-SA",
6
+ "url": "http://creativecommons.org/licenses/by-sa/3.0/"
7
+ },
8
+ {
9
+ "name": "ODbL",
10
+ "url": "http://opendatacommons.org/licenses/odbl/summary/"
11
+ }
12
+ ],
13
+ "rate": {
14
+ "limit": 1,
15
+ "remaining": 0,
16
+ "reset": null
17
+ },
18
+ "results": [ ],
19
+ "status": {
20
+ "code": 402,
21
+ "message": "quota exceeded"
22
+ },
23
+ "thanks": "For using an OpenCage Data API",
24
+ "timestamp": {
25
+ "created_http": "Thu, 07 Aug 2014 13:59:19 GMT",
26
+ "created_unix": 1407419959
27
+ },
28
+ "total_results": 0,
29
+ "we_are_hiring": "http://lokku.com/#jobs"
30
+
31
+ }
@@ -0,0 +1 @@
1
+ {"error":"Address not found"}
@@ -0,0 +1 @@
1
+ {"error":"Invalid IP address"}
@@ -0,0 +1 @@
1
+ {"ip":"80.111.555.555","continent_code":"EU","country_code":"IE","country_name":"Ireland","region_name":"Dublin City","region_code":"D8","city_name":"Dublin","postcode":"8","latitude":53.3331,"longitude":-6.2489,"time_zone":"Europe/Dublin"}
@@ -0,0 +1 @@
1
+ {"error":"Address not found"}
@@ -22,4 +22,10 @@ class HttpClientTest < Test::Unit::TestCase
22
22
  results = Geocoder.search "27701"
23
23
  assert_not_nil results.first
24
24
  end
25
+
26
+ def test_ssl_opt_out
27
+ Geocoder.configure(ip_lookup: :telize, use_https: true)
28
+ results = Geocoder.search "74.200.247.59"
29
+ assert_not_nil results.first
30
+ end
25
31
  end
data/test/test_helper.rb CHANGED
@@ -150,6 +150,13 @@ module Geocoder
150
150
  end
151
151
  end
152
152
 
153
+ class Pointpin
154
+ private
155
+ def default_fixture_filename
156
+ "pointpin_80_111_555_555"
157
+ end
158
+ end
159
+
153
160
  class Maxmind
154
161
  private
155
162
  def default_fixture_filename
@@ -23,7 +23,7 @@ class LookupTest < GeocoderTestCase
23
23
 
24
24
  def test_query_url_contains_values_in_params_hash
25
25
  Geocoder::Lookup.all_services_except_test.each do |l|
26
- next if [:freegeoip, :maxmind_local, :telize].include? l # does not use query string
26
+ next if [:freegeoip, :maxmind_local, :telize, :pointpin].include? l # does not use query string
27
27
  set_api_key!(l)
28
28
  url = Geocoder::Lookup.get(l).query_url(Geocoder::Query.new(
29
29
  "test", :params => {:one_in_the_hand => "two in the bush"}
@@ -87,7 +87,7 @@ class LookupTest < GeocoderTestCase
87
87
  def test_returns_empty_array_on_invalid_key
88
88
  silence_warnings do
89
89
  #Geocoder::Lookup.all_services_except_test.each do |l|
90
- [:bing, :yahoo, :yandex, :maxmind, :cloudmade, :baidu, :baidu_ip].each do |l|
90
+ [:bing, :yahoo, :yandex, :maxmind, :baidu, :baidu_ip].each do |l|
91
91
  Geocoder.configure(:lookup => l)
92
92
  set_api_key!(l)
93
93
  assert_equal [], Geocoder.search("invalid key")
@@ -119,6 +119,12 @@ class LookupTest < GeocoderTestCase
119
119
  assert_match "ak=MY_KEY", g.query_url(Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States"))
120
120
  end
121
121
 
122
+ def test_pointpin_api_key
123
+ Geocoder.configure(:api_key => "MY_KEY")
124
+ g = Geocoder::Lookup::Pointpin.new
125
+ assert_match "/MY_KEY/", g.query_url(Geocoder::Query.new("232.65.123.94"))
126
+ end
127
+
122
128
  def test_google_api_key
123
129
  Geocoder.configure(:api_key => "MY_KEY")
124
130
  g = Geocoder::Lookup::Google.new
@@ -19,7 +19,7 @@ class GeocodioTest < GeocoderTestCase
19
19
  assert_equal "NW", result.postdirectional
20
20
  assert_equal "Washington", result.city
21
21
  assert_equal "1101 Pennsylvania Ave NW, Washington DC, 20004", result.formatted_address
22
- assert_equal({ "lat" => 38.895019, "lng" => -77.028095 }, result.location)
22
+ assert_equal({ "lat" => "38.895019", "lng" => "-77.028095" }, result.location)
23
23
  end
24
24
 
25
25
  def test_no_results
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+ $: << File.join(File.dirname(__FILE__), "..", "..")
3
+ require 'test_helper'
4
+
5
+ class OpencagedataTest < GeocoderTestCase
6
+
7
+ def setup
8
+ Geocoder.configure(lookup: :opencagedata)
9
+ set_api_key!(:opencagedata)
10
+ end
11
+
12
+ def test_result_components
13
+ result = Geocoder.search("Madison Square Garden, New York, NY").first
14
+ assert_equal "West 31st Street", result.street
15
+ assert_match /46, West 31st Street, Koreatown, New York County, 10011, New York City, New York, United States of America/, result.address
16
+
17
+ end
18
+
19
+ def test_opencagedata_query_url_contains_bounds
20
+ lookup = Geocoder::Lookup::Opencagedata.new
21
+ url = lookup.query_url(Geocoder::Query.new(
22
+ "Some street",
23
+ :bounds => [[40.0, -120.0], [39.0, -121.0]]
24
+ ))
25
+ assert_match(/bounds=40.0+%2C-120.0+%2C39.0+%2C-121.0+/, url)
26
+ end
27
+
28
+
29
+ def test_no_results
30
+ results = Geocoder.search("no results")
31
+ assert_equal 0, results.length
32
+ end
33
+
34
+
35
+ def test_opencagedata_reverse_url
36
+ query = Geocoder::Query.new([45.423733, -75.676333])
37
+ assert_match /\bquery=45.423733%2C-75.676333\b/, query.url
38
+ end
39
+
40
+
41
+
42
+ def test_raises_exception_when_invalid_request
43
+ Geocoder.configure(always_raise: [Geocoder::InvalidRequest])
44
+ assert_raises Geocoder::InvalidRequest do
45
+ Geocoder.search("invalid request")
46
+ end
47
+ end
48
+
49
+ def test_raises_exception_when_invalid_api_key
50
+ Geocoder.configure(always_raise: [Geocoder::InvalidApiKey])
51
+ assert_raises Geocoder::InvalidApiKey do
52
+ Geocoder.search("invalid api key")
53
+ end
54
+ end
55
+
56
+
57
+ def test_raises_exception_when_over_query_limit
58
+ Geocoder.configure(:always_raise => [Geocoder::OverQueryLimitError])
59
+ l = Geocoder::Lookup.get(:opencagedata)
60
+ assert_raises Geocoder::OverQueryLimitError do
61
+ l.send(:results, Geocoder::Query.new("over limit"))
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ $: << File.join(File.dirname(__FILE__), "..", "..")
3
+ require 'test_helper'
4
+
5
+ class PointpinTest < GeocoderTestCase
6
+
7
+ def setup
8
+ Geocoder.configure(ip_lookup: :pointpin, api_key: "abc123")
9
+ end
10
+
11
+ def test_result_on_ip_address_search
12
+ result = Geocoder.search("80.111.555.555").first
13
+ assert result.is_a?(Geocoder::Result::Pointpin)
14
+ end
15
+
16
+ def test_result_components
17
+ result = Geocoder.search("80.111.555.555").first
18
+ assert_equal "Dublin, Dublin City, 8, Ireland", result.address
19
+ end
20
+
21
+ def test_no_results
22
+ results = Geocoder.search("10.10.10.10")
23
+ assert_equal 0, results.length
24
+ end
25
+
26
+ def test_invalid_address
27
+ results = Geocoder.search("555.555.555.555")
28
+ assert_equal 0, results.length
29
+ end
30
+ end
@@ -27,4 +27,10 @@ class TelizeTest < GeocoderTestCase
27
27
  results = Geocoder.search("555.555.555.555")
28
28
  assert_equal 0, results.length
29
29
  end
30
+
31
+ def test_uses_http_even_if_use_https_true
32
+ Geocoder.configure(use_https: true)
33
+ result = Geocoder.search("74.200.247.59").first
34
+ assert result.is_a?(Geocoder::Result::Telize)
35
+ end
30
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geocoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Reisner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-11 00:00:00.000000000 Z
11
+ date: 2014-08-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Provides object geocoding (by street or IP address), reverse geocoding
14
14
  (coordinates to street address), distance queries for ActiveRecord and Mongoid,
@@ -51,7 +51,6 @@ files:
51
51
  - lib/geocoder/lookups/baidu_ip.rb
52
52
  - lib/geocoder/lookups/base.rb
53
53
  - lib/geocoder/lookups/bing.rb
54
- - lib/geocoder/lookups/cloudmade.rb
55
54
  - lib/geocoder/lookups/dstk.rb
56
55
  - lib/geocoder/lookups/esri.rb
57
56
  - lib/geocoder/lookups/freegeoip.rb
@@ -65,7 +64,9 @@ files:
65
64
  - lib/geocoder/lookups/maxmind.rb
66
65
  - lib/geocoder/lookups/maxmind_local.rb
67
66
  - lib/geocoder/lookups/nominatim.rb
67
+ - lib/geocoder/lookups/opencagedata.rb
68
68
  - lib/geocoder/lookups/ovi.rb
69
+ - lib/geocoder/lookups/pointpin.rb
69
70
  - lib/geocoder/lookups/smarty_streets.rb
70
71
  - lib/geocoder/lookups/telize.rb
71
72
  - lib/geocoder/lookups/test.rb
@@ -83,7 +84,6 @@ files:
83
84
  - lib/geocoder/results/baidu_ip.rb
84
85
  - lib/geocoder/results/base.rb
85
86
  - lib/geocoder/results/bing.rb
86
- - lib/geocoder/results/cloudmade.rb
87
87
  - lib/geocoder/results/dstk.rb
88
88
  - lib/geocoder/results/esri.rb
89
89
  - lib/geocoder/results/freegeoip.rb
@@ -97,7 +97,9 @@ files:
97
97
  - lib/geocoder/results/maxmind.rb
98
98
  - lib/geocoder/results/maxmind_local.rb
99
99
  - lib/geocoder/results/nominatim.rb
100
+ - lib/geocoder/results/opencagedata.rb
100
101
  - lib/geocoder/results/ovi.rb
102
+ - lib/geocoder/results/pointpin.rb
101
103
  - lib/geocoder/results/smarty_streets.rb
102
104
  - lib/geocoder/results/telize.rb
103
105
  - lib/geocoder/results/test.rb
@@ -167,8 +169,17 @@ files:
167
169
  - test/fixtures/nominatim_madison_square_garden
168
170
  - test/fixtures/nominatim_no_results
169
171
  - test/fixtures/nominatim_over_limit
172
+ - test/fixtures/opencagedata_invalid_api_key
173
+ - test/fixtures/opencagedata_invalid_request
174
+ - test/fixtures/opencagedata_madison_square_garden
175
+ - test/fixtures/opencagedata_no_results
176
+ - test/fixtures/opencagedata_over_limit
170
177
  - test/fixtures/ovi_madison_square_garden
171
178
  - test/fixtures/ovi_no_results
179
+ - test/fixtures/pointpin_10_10_10_10
180
+ - test/fixtures/pointpin_555_555_555_555
181
+ - test/fixtures/pointpin_80_111_555_555
182
+ - test/fixtures/pointpin_no_results
172
183
  - test/fixtures/smarty_streets_11211
173
184
  - test/fixtures/smarty_streets_madison_square_garden
174
185
  - test/fixtures/smarty_streets_no_results
@@ -211,6 +222,8 @@ files:
211
222
  - test/unit/lookups/maxmind_local_test.rb
212
223
  - test/unit/lookups/maxmind_test.rb
213
224
  - test/unit/lookups/nominatim_test.rb
225
+ - test/unit/lookups/opencagedata_test.rb
226
+ - test/unit/lookups/pointpin_test.rb
214
227
  - test/unit/lookups/smarty_streets_test.rb
215
228
  - test/unit/lookups/telize_test.rb
216
229
  - test/unit/lookups/yahoo_test.rb
@@ -1,35 +0,0 @@
1
- require 'geocoder/lookups/base'
2
- require 'geocoder/results/cloudmade'
3
-
4
- module Geocoder::Lookup
5
- class Cloudmade < Base
6
-
7
- def name
8
- "Cloudmade"
9
- end
10
-
11
- def query_url(query)
12
- "http://geocoding.cloudmade.com/#{configuration.api_key}/geocoding/v2/find.js?#{url_query_string(query)}"
13
- end
14
-
15
- def required_api_key_parts
16
- ["key"]
17
- end
18
-
19
- private
20
-
21
- def results(query)
22
- data = fetch_data(query)
23
- (data && data['features']) || []
24
- end
25
-
26
- def query_url_params(query)
27
- {
28
- :query => query.sanitized_text,
29
- :return_location => true,
30
- :return_geometry => false
31
- }.merge(super)
32
- end
33
-
34
- end
35
- end
@@ -1,39 +0,0 @@
1
- require 'geocoder/results/base'
2
-
3
- module Geocoder::Result
4
- class Cloudmade < Base
5
-
6
- def coordinates
7
- @data["centroid"]["coordinates"]
8
- end
9
-
10
- def street
11
- @data["location"]["road"]
12
- end
13
-
14
- def city
15
- @data["location"]["city"]
16
- end
17
-
18
- def state
19
- @data["location"]["county"]
20
- end
21
- alias_method :state_code, :state
22
-
23
- def country
24
- @data["location"]["country"]
25
- end
26
- alias_method :country_code, :country
27
-
28
- def postal_code
29
- @data["location"]["postcode"]
30
- end
31
-
32
- def address
33
- [street, city, state, postal_code, country].compact.reject{|s| s.length == 0 }.join(", ")
34
- end
35
-
36
- end
37
- end
38
-
39
-