graticule 2.2.0 → 2.3.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.
- data/CHANGELOG.txt +9 -0
- data/lib/graticule/distance/spherical.rb +2 -3
- data/lib/graticule/geocoder/base.rb +1 -1
- data/lib/graticule/geocoder/google.rb +81 -75
- data/lib/graticule/geocoder/mapquest.rb +28 -10
- data/lib/graticule/version.rb +1 -1
- metadata +63 -17
data/CHANGELOG.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
2.3.0 (2013-04-01)
|
2
|
+
* Google v3 API [Adamlb]
|
3
|
+
* Escape XML entities in GeoCoder::MapQuest queries [Simon Coffey]
|
4
|
+
|
5
|
+
2.2.0 (2011-09-14)
|
6
|
+
* Added yandex geocoder
|
7
|
+
* Lots of other changes since September 2009.
|
8
|
+
Check https://github.com/collectiveidea/graticule/compare/v0.2.12...master for more info
|
9
|
+
|
1
10
|
* Added freethepostcode.org geocoder [Chris Lowis]
|
2
11
|
|
3
12
|
0.2.12 (2009-09-06)
|
@@ -38,16 +38,15 @@ module Graticule
|
|
38
38
|
:latitude_column => 'latitude',
|
39
39
|
:longitude_column => 'longitude'
|
40
40
|
}.merge(options)
|
41
|
-
%{(ACOS(
|
41
|
+
%{(ACOS(LEAST(1,
|
42
42
|
SIN(RADIANS(#{options[:latitude]})) *
|
43
43
|
SIN(RADIANS(#{options[:latitude_column]})) +
|
44
44
|
COS(RADIANS(#{options[:latitude]})) *
|
45
45
|
COS(RADIANS(#{options[:latitude_column]})) *
|
46
46
|
COS(RADIANS(#{options[:longitude_column]}) - RADIANS(#{options[:longitude]}))
|
47
|
-
) * #{Graticule::Distance::EARTH_RADIUS[options[:units].to_sym]})
|
47
|
+
)) * #{Graticule::Distance::EARTH_RADIUS[options[:units].to_sym]})
|
48
48
|
}.gsub("\n", '').squeeze(" ")
|
49
49
|
end
|
50
|
-
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -81,6 +81,7 @@ module Graticule #:nodoc:
|
|
81
81
|
check_error(response)
|
82
82
|
return parse_response(response)
|
83
83
|
rescue OpenURI::HTTPError => e
|
84
|
+
raise e.inspect
|
84
85
|
check_error(prepare_response(e.io.read))
|
85
86
|
raise
|
86
87
|
end
|
@@ -91,7 +92,6 @@ module Graticule #:nodoc:
|
|
91
92
|
escaped_params = params.sort_by { |k,v| k.to_s }.map do |k,v|
|
92
93
|
"#{escape k.to_s}=#{escape v.to_s}"
|
93
94
|
end
|
94
|
-
|
95
95
|
url = @url.dup
|
96
96
|
url.query = escaped_params.join '&'
|
97
97
|
return url
|
@@ -1,93 +1,102 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
+
require 'json'
|
2
3
|
module Graticule #:nodoc:
|
3
4
|
module Geocoder #:nodoc:
|
4
|
-
|
5
|
-
# First you need a Google Maps API key. You can register for one here:
|
6
|
-
# http://www.google.com/apis/maps/signup.html
|
7
|
-
#
|
8
|
-
# gg = Graticule.service(:google).new(MAPS_API_KEY)
|
5
|
+
# gg = Graticule.service(:google).new(MAPS_API_KEY) API Key is not required
|
9
6
|
# location = gg.locate '1600 Amphitheater Pkwy, Mountain View, CA'
|
10
7
|
# p location.coordinates
|
11
8
|
# #=> [37.423111, -122.081783
|
12
9
|
#
|
13
10
|
class Google < Base
|
14
|
-
#
|
15
|
-
|
16
|
-
# http://www.google.com/apis/maps/documentation/reference.html#GGeoAddressAccuracy
|
17
|
-
PRECISION = {
|
18
|
-
0 => Precision::Unknown, # Unknown location.
|
19
|
-
1 => Precision::Country, # Country level accuracy.
|
20
|
-
2 => Precision::Region, # Region (state, province, prefecture, etc.) level accuracy.
|
21
|
-
3 => Precision::Region, # Sub-region (county, municipality, etc.) level accuracy.
|
22
|
-
4 => Precision::Locality, # Town (city, village) level accuracy.
|
23
|
-
5 => Precision::PostalCode, # Post code (zip code) level accuracy.
|
24
|
-
6 => Precision::Street, # Street level accuracy.
|
25
|
-
7 => Precision::Street, # Intersection level accuracy.
|
26
|
-
8 => Precision::Address, # Address level accuracy.
|
27
|
-
9 => Precision::Premise # Premise (building name, property name, shopping center, etc.) level accuracy.
|
28
|
-
}
|
11
|
+
# https://developers.google.com/maps/documentation/geocoding/
|
29
12
|
|
30
13
|
def initialize(key)
|
31
14
|
@key = key
|
32
|
-
@url = URI.parse 'http://maps.
|
15
|
+
@url = URI.parse 'http://maps.googleapis.com/maps/api/geocode/json'
|
33
16
|
end
|
34
17
|
|
35
18
|
# Locates +address+ returning a Location
|
36
19
|
def locate(address)
|
37
|
-
get :
|
20
|
+
get :address => address.is_a?(String) ? address : location_from_params(address).to_s
|
38
21
|
end
|
39
22
|
|
40
23
|
private
|
41
|
-
class
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
class Placemark
|
50
|
-
include HappyMapper
|
51
|
-
tag 'Placemark'
|
52
|
-
element :coordinates, String, :deep => true
|
53
|
-
has_one :address, Address
|
54
|
-
|
55
|
-
attr_reader :longitude, :latitude
|
56
|
-
|
57
|
-
with_options :deep => true, :namespace => 'urn:oasis:names:tc:ciq:xsdschema:xAL:2.0' do |map|
|
58
|
-
map.element :street, String, :tag => 'ThoroughfareName'
|
59
|
-
map.element :locality, String, :tag => 'LocalityName'
|
60
|
-
map.element :region, String, :tag => 'AdministrativeAreaName'
|
61
|
-
map.element :postal_code, String, :tag => 'PostalCodeNumber'
|
62
|
-
map.element :country, String, :tag => 'CountryNameCode'
|
24
|
+
class Result
|
25
|
+
attr_accessor :latitude, :longitude, :street_number, :route, :locality, :region, :postal_code, :country, :precision, :formatted_address
|
26
|
+
def initialize(attribs)
|
27
|
+
@latitude = attribs["geometry"]["location"]["lat"]
|
28
|
+
@longitude = attribs["geometry"]["location"]["lng"]
|
29
|
+
@formatted_address = attribs["formatted_address"]
|
30
|
+
@precision = determine_precision(attribs["types"])
|
31
|
+
parse_address_components(attribs["address_components"])
|
63
32
|
end
|
64
33
|
|
65
|
-
def
|
66
|
-
|
34
|
+
def parse_address_components(components)
|
35
|
+
components.each do |component|
|
36
|
+
component["types"].each do |type|
|
37
|
+
case type
|
38
|
+
when "street_number"
|
39
|
+
@street_number = component["short_name"]
|
40
|
+
when "route"
|
41
|
+
@route = component["short_name"]
|
42
|
+
when "locality"
|
43
|
+
@locality = component["long_name"]
|
44
|
+
when "administrative_area_level_1"
|
45
|
+
@region = component["short_name"]
|
46
|
+
when "country"
|
47
|
+
@country = component["short_name"]
|
48
|
+
when "postal_code"
|
49
|
+
@postal_code = component["long_name"]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
67
53
|
end
|
68
54
|
|
69
|
-
def
|
70
|
-
|
55
|
+
def street
|
56
|
+
"#{@street_number.to_s}#{" " unless @street_number.blank? || @route.blank?}#{@route.to_s}"
|
71
57
|
end
|
72
58
|
|
73
|
-
def
|
74
|
-
|
59
|
+
def determine_precision(types)
|
60
|
+
precision = Precision::Unknown
|
61
|
+
types.each do |type|
|
62
|
+
precision = case type
|
63
|
+
when "premise", "subpremise"
|
64
|
+
Precision::Premise
|
65
|
+
when "street_address"
|
66
|
+
Precision::Address
|
67
|
+
when "route", "intersection"
|
68
|
+
Precision::Street
|
69
|
+
when "postal_code"
|
70
|
+
Precision::PostalCode
|
71
|
+
when "locality","sublocality","neighborhood"
|
72
|
+
Precision::Locality
|
73
|
+
when "administrative_area_level_1", "administrative_area_level_2","administrative_area_level_3"
|
74
|
+
Precision::Region
|
75
|
+
when "country"
|
76
|
+
Precision::Country
|
77
|
+
else
|
78
|
+
precision
|
79
|
+
end
|
80
|
+
end
|
81
|
+
return precision
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
78
85
|
class Response
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
86
|
+
attr_reader :results, :status
|
87
|
+
def initialize(json)
|
88
|
+
result = JSON.parse(json)
|
89
|
+
@results = result["results"].collect{|attribs| Result.new(attribs)}
|
90
|
+
@status = result["status"]
|
91
|
+
end
|
83
92
|
end
|
84
93
|
|
85
|
-
def prepare_response(
|
86
|
-
Response.
|
94
|
+
def prepare_response(json)
|
95
|
+
Response.new(json)
|
87
96
|
end
|
88
97
|
|
89
98
|
def parse_response(response) #:nodoc:
|
90
|
-
result = response.
|
99
|
+
result = response.results.first
|
91
100
|
Location.new(
|
92
101
|
:latitude => result.latitude,
|
93
102
|
:longitude => result.longitude,
|
@@ -100,31 +109,28 @@ module Graticule #:nodoc:
|
|
100
109
|
)
|
101
110
|
end
|
102
111
|
|
103
|
-
# Extracts and raises an error from +
|
112
|
+
# Extracts and raises an error from +json+, if any.
|
104
113
|
def check_error(response) #:nodoc:
|
105
|
-
case response.
|
106
|
-
when
|
107
|
-
when
|
108
|
-
raise Error, 'server error'
|
109
|
-
when 601 then
|
110
|
-
raise AddressError, 'missing address'
|
111
|
-
when 602 then
|
114
|
+
case response.status
|
115
|
+
when "OK" then # ignore, ok
|
116
|
+
when "ZERO_RESULTS" then
|
112
117
|
raise AddressError, 'unknown address'
|
113
|
-
when
|
114
|
-
raise
|
115
|
-
when
|
116
|
-
raise CredentialsError, '
|
117
|
-
when
|
118
|
-
raise
|
118
|
+
when "OVER_QUERY_LIMIT"
|
119
|
+
raise CredentialsError, 'over query limit'
|
120
|
+
when "REQUEST_DENIED"
|
121
|
+
raise CredentialsError, 'request denied'
|
122
|
+
when "INVALID_REQUEST"
|
123
|
+
raise AddressError, 'missing address'
|
124
|
+
when "UNKNOWN_ERROR"
|
125
|
+
raise Error, "unknown server error. Try again."
|
119
126
|
else
|
120
|
-
raise Error, "
|
127
|
+
raise Error, "unkown error #{response.status}"
|
121
128
|
end
|
122
129
|
end
|
123
130
|
|
124
|
-
# Creates a URL from the Hash +params
|
125
|
-
# sets the output type to 'xml'.
|
131
|
+
# Creates a URL from the Hash +params+..
|
126
132
|
def make_url(params) #:nodoc:
|
127
|
-
super params.merge(:key => @key, :
|
133
|
+
super params.merge(:key => @key, :sensor => false)
|
128
134
|
end
|
129
135
|
end
|
130
136
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'htmlentities'
|
2
|
+
|
1
3
|
# encoding: UTF-8
|
2
4
|
module Graticule #:nodoc:
|
3
5
|
module Geocoder #:nodoc:
|
@@ -43,13 +45,36 @@ module Graticule #:nodoc:
|
|
43
45
|
protected
|
44
46
|
|
45
47
|
def make_url(params) #:nodoc
|
46
|
-
|
47
|
-
#{address_string(params[:q])}#{authentication_string}</Geocode>"
|
48
|
+
request = Mapquest::Request.new(params[:q], @client_id, @password)
|
48
49
|
url = @url.dup
|
49
|
-
url.query = escape(query)
|
50
|
+
url.query = escape(request.query)
|
50
51
|
url
|
51
52
|
end
|
52
53
|
|
54
|
+
class Request
|
55
|
+
def initialize(address, client_id, password)
|
56
|
+
@address = address
|
57
|
+
@client_id = client_id
|
58
|
+
@password = password
|
59
|
+
end
|
60
|
+
|
61
|
+
def query
|
62
|
+
"e=5&<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><Geocode Version=\"1\">#{address_string}#{authentication_string}</Geocode>"
|
63
|
+
end
|
64
|
+
|
65
|
+
def address_string
|
66
|
+
"<Address><Street>#{escaped_address}</Street></Address><GeocodeOptionsCollection Count=\"0\"/>"
|
67
|
+
end
|
68
|
+
|
69
|
+
def authentication_string
|
70
|
+
"<Authentication Version=\"2\"><Password>#{@password}</Password><ClientId>#{@client_id}</ClientId></Authentication>"
|
71
|
+
end
|
72
|
+
|
73
|
+
def escaped_address
|
74
|
+
HTMLEntities.new.encode(@address, :basic)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
53
78
|
class Address
|
54
79
|
include HappyMapper
|
55
80
|
tag 'GeoAddress'
|
@@ -96,13 +121,6 @@ module Graticule #:nodoc:
|
|
96
121
|
def check_error(xml) #:nodoc
|
97
122
|
end
|
98
123
|
|
99
|
-
def authentication_string
|
100
|
-
"<Authentication Version=\"2\"><Password>#{@password}</Password><ClientId>#{@client_id}</ClientId></Authentication>"
|
101
|
-
end
|
102
|
-
|
103
|
-
def address_string(query)
|
104
|
-
"<Address><Street>#{query}</Street></Address><GeocodeOptionsCollection Count=\"0\"/>"
|
105
|
-
end
|
106
124
|
end
|
107
125
|
end
|
108
126
|
end
|
data/lib/graticule/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graticule
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-04-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
17
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,15 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
26
31
|
- !ruby/object:Gem::Dependency
|
27
32
|
name: i18n
|
28
|
-
requirement:
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
29
34
|
none: false
|
30
35
|
requirements:
|
31
36
|
- - ! '>='
|
@@ -33,10 +38,31 @@ dependencies:
|
|
33
38
|
version: '0'
|
34
39
|
type: :runtime
|
35
40
|
prerelease: false
|
36
|
-
version_requirements:
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: htmlentities
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
37
63
|
- !ruby/object:Gem::Dependency
|
38
64
|
name: happymapper
|
39
|
-
requirement:
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
40
66
|
none: false
|
41
67
|
requirements:
|
42
68
|
- - ! '>='
|
@@ -44,10 +70,15 @@ dependencies:
|
|
44
70
|
version: 0.3.0
|
45
71
|
type: :runtime
|
46
72
|
prerelease: false
|
47
|
-
version_requirements:
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 0.3.0
|
48
79
|
- !ruby/object:Gem::Dependency
|
49
80
|
name: json
|
50
|
-
requirement:
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
51
82
|
none: false
|
52
83
|
requirements:
|
53
84
|
- - ! '>='
|
@@ -55,10 +86,15 @@ dependencies:
|
|
55
86
|
version: '0'
|
56
87
|
type: :runtime
|
57
88
|
prerelease: false
|
58
|
-
version_requirements:
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
59
95
|
- !ruby/object:Gem::Dependency
|
60
96
|
name: mocha
|
61
|
-
requirement:
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
62
98
|
none: false
|
63
99
|
requirements:
|
64
100
|
- - ! '>='
|
@@ -66,10 +102,15 @@ dependencies:
|
|
66
102
|
version: '0'
|
67
103
|
type: :development
|
68
104
|
prerelease: false
|
69
|
-
version_requirements:
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
70
111
|
- !ruby/object:Gem::Dependency
|
71
112
|
name: rcov
|
72
|
-
requirement:
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
73
114
|
none: false
|
74
115
|
requirements:
|
75
116
|
- - ! '>='
|
@@ -77,7 +118,12 @@ dependencies:
|
|
77
118
|
version: '0'
|
78
119
|
type: :development
|
79
120
|
prerelease: false
|
80
|
-
version_requirements:
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
81
127
|
description: Graticule is a geocoding API that provides a common interface to all
|
82
128
|
the popular services, including Google, Yahoo, Geocoder.us, and MetaCarta.
|
83
129
|
email: brandon@opensoul.org
|
@@ -135,7 +181,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
181
|
version: '0'
|
136
182
|
segments:
|
137
183
|
- 0
|
138
|
-
hash:
|
184
|
+
hash: 3804880588215325222
|
139
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
186
|
none: false
|
141
187
|
requirements:
|
@@ -144,10 +190,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
190
|
version: '0'
|
145
191
|
segments:
|
146
192
|
- 0
|
147
|
-
hash:
|
193
|
+
hash: 3804880588215325222
|
148
194
|
requirements: []
|
149
195
|
rubyforge_project: graticule
|
150
|
-
rubygems_version: 1.8.
|
196
|
+
rubygems_version: 1.8.25
|
151
197
|
signing_key:
|
152
198
|
specification_version: 3
|
153
199
|
summary: API for using all the popular geocoding services.
|