geokit 1.8.3 → 1.8.4
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.
- data/CHANGELOG.md +5 -0
- data/geokit.gemspec +1 -0
- data/lib/geokit/geocoders.rb +9 -10
- data/lib/geokit/geocoders/bing.rb +1 -1
- data/lib/geokit/geocoders/google.rb +16 -11
- data/lib/geokit/geocoders/ip.rb +1 -1
- data/lib/geokit/mappable.rb +3 -5
- data/lib/geokit/net_adapter/net_http.rb +21 -0
- data/lib/geokit/net_adapter/typhoeus.rb +13 -0
- data/lib/geokit/polygon.rb +15 -21
- data/lib/geokit/version.rb +1 -1
- data/test/helper.rb +5 -1
- data/test/test_mappable.rb +12 -0
- data/test/test_net_adapter.rb +46 -0
- data/test/test_polygon_contains.rb +2 -2
- metadata +26 -4
data/CHANGELOG.md
CHANGED
data/geokit.gemspec
CHANGED
data/lib/geokit/geocoders.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'net/http'
|
2
|
+
require 'geokit/net_adapter/net_http'
|
3
|
+
require 'geokit/net_adapter/typhoeus'
|
2
4
|
require 'ipaddr'
|
3
5
|
require 'rexml/document'
|
4
6
|
require 'yaml'
|
@@ -37,6 +39,7 @@ module Geokit
|
|
37
39
|
@@logger=Logger.new(STDOUT)
|
38
40
|
@@logger.level=Logger::INFO
|
39
41
|
@@domain = nil
|
42
|
+
@@net_adapter = Geokit::NetAdapter::NetHttp
|
40
43
|
|
41
44
|
def self.__define_accessors
|
42
45
|
class_variables.each do |v|
|
@@ -141,15 +144,11 @@ module Geokit
|
|
141
144
|
|
142
145
|
# Wraps the geocoder call around a proxy if necessary.
|
143
146
|
def self.do_get(url)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
proxy_uri = URI.parse(proxy_uri_string)
|
150
|
-
net_http_args += [proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password]
|
151
|
-
end
|
152
|
-
Net::HTTP::new(*net_http_args).start { |http| http.request(req) }
|
147
|
+
net_adapter.do_get(url)
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.net_adapter
|
151
|
+
Geokit::Geocoders::net_adapter
|
153
152
|
end
|
154
153
|
|
155
154
|
def self.provider_name
|
@@ -174,7 +173,7 @@ module Geokit
|
|
174
173
|
|
175
174
|
def self.process(format, url, *args)
|
176
175
|
res = call_geocoder_service(url)
|
177
|
-
return GeoLoc.new
|
176
|
+
return GeoLoc.new unless net_adapter.success?(res)
|
178
177
|
parse format, res.body, *args
|
179
178
|
end
|
180
179
|
|
@@ -11,7 +11,7 @@ module Geokit
|
|
11
11
|
def self.do_geocode(address)
|
12
12
|
url = submit_url(address)
|
13
13
|
res = call_geocoder_service(url)
|
14
|
-
return GeoLoc.new
|
14
|
+
return GeoLoc.new unless net_adapter.success?(res)
|
15
15
|
xml = transcode_to_utf8(res.body)
|
16
16
|
parse :xml, xml
|
17
17
|
end
|
@@ -140,36 +140,41 @@ module Geokit
|
|
140
140
|
loc.lat = ll['lat'].to_f
|
141
141
|
loc.lng = ll['lng'].to_f
|
142
142
|
|
143
|
+
set_bounds(loc, addr)
|
144
|
+
|
145
|
+
loc
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.set_bounds(loc, addr)
|
143
149
|
viewport = addr['geometry']['viewport']
|
144
150
|
ne = Geokit::LatLng.from_json(viewport['northeast'])
|
145
151
|
sw = Geokit::LatLng.from_json(viewport['southwest'])
|
146
152
|
loc.suggested_bounds = Geokit::Bounds.new(sw, ne)
|
147
|
-
|
148
|
-
loc
|
149
153
|
end
|
150
154
|
|
151
155
|
def self.set_address_components(loc, addr)
|
152
156
|
addr['address_components'].each do |comp|
|
157
|
+
types = comp['types']
|
153
158
|
case
|
154
|
-
when
|
159
|
+
when types.include?("subpremise")
|
155
160
|
loc.sub_premise = comp['short_name']
|
156
|
-
when
|
161
|
+
when types.include?("street_number")
|
157
162
|
loc.street_number = comp['short_name']
|
158
|
-
when
|
163
|
+
when types.include?("route")
|
159
164
|
loc.street_name = comp['long_name']
|
160
|
-
when
|
165
|
+
when types.include?("locality")
|
161
166
|
loc.city = comp['long_name']
|
162
|
-
when
|
167
|
+
when types.include?("administrative_area_level_1")
|
163
168
|
loc.state = comp['short_name']
|
164
169
|
loc.province = comp['short_name']
|
165
|
-
when
|
170
|
+
when types.include?("postal_code")
|
166
171
|
loc.zip = comp['long_name']
|
167
|
-
when
|
172
|
+
when types.include?("country")
|
168
173
|
loc.country_code = comp['short_name']
|
169
174
|
loc.country = comp['long_name']
|
170
|
-
when
|
175
|
+
when types.include?("administrative_area_level_2")
|
171
176
|
loc.district = comp['long_name']
|
172
|
-
when
|
177
|
+
when types.include?('neighborhood')
|
173
178
|
loc.neighborhood = comp['short_name']
|
174
179
|
end
|
175
180
|
end
|
data/lib/geokit/geocoders/ip.rb
CHANGED
@@ -13,7 +13,7 @@ module Geokit
|
|
13
13
|
return GeoLoc.new unless valid_ip?(ip)
|
14
14
|
url = submit_url(ip)
|
15
15
|
res = call_geocoder_service(url)
|
16
|
-
return GeoLoc.new
|
16
|
+
return GeoLoc.new unless net_adapter.success?(res)
|
17
17
|
ensure_utf8_encoding(res)
|
18
18
|
body = res.body
|
19
19
|
body = body.encode('UTF-8') if body.respond_to? :encode
|
data/lib/geokit/mappable.rb
CHANGED
@@ -60,12 +60,10 @@ module Geokit
|
|
60
60
|
Math.sqrt(lat_length ** 2 + lng_length ** 2)
|
61
61
|
end
|
62
62
|
|
63
|
+
# Ruby 1.9 raises {Math::DomainError}, but it is not defined in Ruby 1.8
|
63
64
|
def math_error_classes
|
64
|
-
|
65
|
-
|
66
|
-
# Ruby 1.9 raises {Math::DomainError}, but it is not defined in Ruby
|
67
|
-
# 1.8. Backwards-compatibly rescue both errors.
|
68
|
-
error_classes << Math::DomainError if defined?(Math::DomainError)
|
65
|
+
return [Errno::EDOM, Math::DomainError] if defined?(Math::DomainError)
|
66
|
+
[Errno::EDOM]
|
69
67
|
end
|
70
68
|
|
71
69
|
# Returns heading in degrees (0 is north, 90 is east, 180 is south, etc)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Geokit
|
2
|
+
module NetAdapter
|
3
|
+
class NetHttp
|
4
|
+
def self.do_get(url)
|
5
|
+
uri = URI.parse(url)
|
6
|
+
req = Net::HTTP::Get.new(url)
|
7
|
+
req.basic_auth(uri.user, uri.password) if uri.userinfo
|
8
|
+
net_http_args = [uri.host, uri.port]
|
9
|
+
if (proxy_uri_string = Geokit::Geocoders::proxy)
|
10
|
+
proxy_uri = URI.parse(proxy_uri_string)
|
11
|
+
net_http_args += [proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password]
|
12
|
+
end
|
13
|
+
Net::HTTP::new(*net_http_args).start { |http| http.request(req) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.success?(response)
|
17
|
+
response.is_a?(Net::HTTPSuccess)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/geokit/polygon.rb
CHANGED
@@ -2,42 +2,36 @@ module Geokit
|
|
2
2
|
# A complex polygon made of multiple points. End point must equal start point to close the poly.
|
3
3
|
class Polygon
|
4
4
|
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :points
|
6
6
|
|
7
|
+
# Pass in an array of Geokit::LatLng
|
7
8
|
def initialize(points)
|
8
|
-
|
9
|
-
@poly_x = []
|
10
|
-
@poly_y = []
|
11
|
-
|
12
|
-
points.each do |point|
|
13
|
-
@poly_x << point.lng
|
14
|
-
@poly_y << point.lat
|
15
|
-
end
|
9
|
+
@points = points
|
16
10
|
|
17
11
|
# A Polygon must be 'closed', the last point equal to the first point
|
18
|
-
|
19
|
-
|
20
|
-
@poly_x << @poly_x[0]
|
21
|
-
@poly_y << @poly_y[0]
|
22
|
-
end
|
23
|
-
|
12
|
+
# Append the first point to the array to close the polygon
|
13
|
+
@points << points[0] if points[0] != points[-1]
|
24
14
|
end
|
25
15
|
|
26
16
|
def contains?(point)
|
27
|
-
|
17
|
+
last_point = @points[-1]
|
28
18
|
oddNodes = false
|
29
19
|
x = point.lng
|
30
20
|
y = point.lat
|
31
21
|
|
32
|
-
for
|
33
|
-
|
34
|
-
|
35
|
-
|
22
|
+
for p in @points
|
23
|
+
yi = p.lat
|
24
|
+
xi = p.lng
|
25
|
+
yj = last_point.lat
|
26
|
+
xj = last_point.lng
|
27
|
+
if (yi < y && yj >= y ||
|
28
|
+
yj < y && yi >= y)
|
29
|
+
if (xi + (y - yi) / (yj - yi) * (xj - xi) < x)
|
36
30
|
oddNodes = !oddNodes
|
37
31
|
end
|
38
32
|
end
|
39
33
|
|
40
|
-
|
34
|
+
last_point = p
|
41
35
|
end
|
42
36
|
|
43
37
|
oddNodes
|
data/lib/geokit/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -11,7 +11,7 @@ end
|
|
11
11
|
require 'geoip'
|
12
12
|
|
13
13
|
if ENV['COVERAGE']
|
14
|
-
COVERAGE_THRESHOLD =
|
14
|
+
COVERAGE_THRESHOLD = 91
|
15
15
|
require 'simplecov'
|
16
16
|
require 'simplecov-rcov'
|
17
17
|
require 'coveralls'
|
@@ -42,6 +42,10 @@ class MockSuccess < Net::HTTPSuccess #:nodoc: all
|
|
42
42
|
def initialize
|
43
43
|
@header = {}
|
44
44
|
end
|
45
|
+
|
46
|
+
def success? # Typhoeus
|
47
|
+
true
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
class MockFailure < Net::HTTPServiceUnavailable #:nodoc: all
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
class MappableTest < Test::Unit::TestCase #:nodoc: all
|
4
|
+
|
5
|
+
def test_math_error_classes
|
6
|
+
error_case = 0.49 * 180
|
7
|
+
from = Geokit::LatLng.new(error_case, error_case)
|
8
|
+
to = Geokit::LatLng.new(error_case, error_case)
|
9
|
+
assert_equal 0.0, Geokit::LatLng.distance_between_sphere(from, to, :kms)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
# Base class for testing geocoders.
|
4
|
+
class NetAdapterTest < Test::Unit::TestCase #:nodoc: all
|
5
|
+
class Geokit::Geocoders::CachedGeocoder < Geokit::Geocoders::Geocoder
|
6
|
+
def self.parse_json(hash)
|
7
|
+
hash
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class SuperSimpleCache
|
12
|
+
def initialize
|
13
|
+
@cache = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def write(key, value)
|
17
|
+
@cache[key] = value
|
18
|
+
end
|
19
|
+
|
20
|
+
def fetch(key)
|
21
|
+
@cache[key]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
RESULT = '{"name":"json"}'
|
26
|
+
RESULT_HASH = {"name" => "json"}
|
27
|
+
|
28
|
+
# Defines common test fixtures.
|
29
|
+
def setup
|
30
|
+
@url = 'http://www.cacheme.com'
|
31
|
+
@address = 'San Francisco, CA'
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_cache
|
35
|
+
old_adapter = Geokit::Geocoders::net_adapter
|
36
|
+
Geokit::Geocoders::net_adapter = Geokit::NetAdapter::Typhoeus
|
37
|
+
Typhoeus::Config.cache = SuperSimpleCache
|
38
|
+
success = MockSuccess.new
|
39
|
+
success.expects(:body).returns(RESULT)
|
40
|
+
url = 'http://www.cacheme.com'
|
41
|
+
Geokit::NetAdapter::Typhoeus.expects(:do_get).with(@url).returns(success)
|
42
|
+
assert_equal RESULT_HASH, Geokit::Geocoders::CachedGeocoder.process(:json, @url)
|
43
|
+
Typhoeus::Config.cache = nil
|
44
|
+
Geokit::Geocoders::net_adapter = old_adapter
|
45
|
+
end
|
46
|
+
end
|
@@ -93,8 +93,8 @@ class PolygonTest < Test::Unit::TestCase #:nodoc: all
|
|
93
93
|
#puts "\t Does poly_x[0] (#{@open_polygon.poly_x[0]}) == poly_x[-1] (#{@open_polygon.poly_x[-1]}) ?"
|
94
94
|
#puts "\t Does poly_y[0] (#{@open_polygon.poly_y[0]}) == poly_y[-1] (#{@open_polygon.poly_y[-1]}) ?"
|
95
95
|
|
96
|
-
assert @open_polygon.
|
97
|
-
assert @open_polygon.
|
96
|
+
assert @open_polygon.points[0].lng == @open_polygon.points[-1].lng
|
97
|
+
assert @open_polygon.points[0].lat == @open_polygon.points[-1].lat
|
98
98
|
|
99
99
|
end
|
100
100
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geokit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
4
|
+
version: 1.8.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2014-01-12 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: multi_json
|
@@ -158,6 +158,22 @@ dependencies:
|
|
158
158
|
- - ! '>='
|
159
159
|
- !ruby/object:Gem::Version
|
160
160
|
version: '0'
|
161
|
+
- !ruby/object:Gem::Dependency
|
162
|
+
name: typhoeus
|
163
|
+
requirement: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ! '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
type: :development
|
170
|
+
prerelease: false
|
171
|
+
version_requirements: !ruby/object:Gem::Requirement
|
172
|
+
none: false
|
173
|
+
requirements:
|
174
|
+
- - ! '>='
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '0'
|
161
177
|
description: Geokit provides geocoding and distance calculation in an easy-to-use
|
162
178
|
API
|
163
179
|
email:
|
@@ -220,6 +236,8 @@ files:
|
|
220
236
|
- lib/geokit/lat_lng.rb
|
221
237
|
- lib/geokit/mappable.rb
|
222
238
|
- lib/geokit/multi_geocoder.rb
|
239
|
+
- lib/geokit/net_adapter/net_http.rb
|
240
|
+
- lib/geokit/net_adapter/typhoeus.rb
|
223
241
|
- lib/geokit/polygon.rb
|
224
242
|
- lib/geokit/version.rb
|
225
243
|
- test/helper.rb
|
@@ -236,9 +254,11 @@ files:
|
|
236
254
|
- test/test_inflector.rb
|
237
255
|
- test/test_ipgeocoder.rb
|
238
256
|
- test/test_latlng.rb
|
257
|
+
- test/test_mappable.rb
|
239
258
|
- test/test_maxmind_geocoder.rb
|
240
259
|
- test/test_multi_geocoder.rb
|
241
260
|
- test/test_multi_ip_geocoder.rb
|
261
|
+
- test/test_net_adapter.rb
|
242
262
|
- test/test_openstreetmap_geocoder.rb
|
243
263
|
- test/test_polygon_contains.rb
|
244
264
|
- test/test_ripe_geocoder.rb
|
@@ -262,7 +282,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
262
282
|
version: '0'
|
263
283
|
segments:
|
264
284
|
- 0
|
265
|
-
hash: -
|
285
|
+
hash: -1117828600571501675
|
266
286
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
267
287
|
none: false
|
268
288
|
requirements:
|
@@ -271,7 +291,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
271
291
|
version: '0'
|
272
292
|
segments:
|
273
293
|
- 0
|
274
|
-
hash: -
|
294
|
+
hash: -1117828600571501675
|
275
295
|
requirements: []
|
276
296
|
rubyforge_project:
|
277
297
|
rubygems_version: 1.8.25
|
@@ -293,9 +313,11 @@ test_files:
|
|
293
313
|
- test/test_inflector.rb
|
294
314
|
- test/test_ipgeocoder.rb
|
295
315
|
- test/test_latlng.rb
|
316
|
+
- test/test_mappable.rb
|
296
317
|
- test/test_maxmind_geocoder.rb
|
297
318
|
- test/test_multi_geocoder.rb
|
298
319
|
- test/test_multi_ip_geocoder.rb
|
320
|
+
- test/test_net_adapter.rb
|
299
321
|
- test/test_openstreetmap_geocoder.rb
|
300
322
|
- test/test_polygon_contains.rb
|
301
323
|
- test/test_ripe_geocoder.rb
|