graticule 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|