GUI-graticule 0.2.7.2 → 0.2.7.3

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/Manifest.txt CHANGED
@@ -26,6 +26,8 @@ lib/graticule/geocoder/postcode_anywhere.rb
26
26
  lib/graticule/geocoder/rest.rb
27
27
  lib/graticule/geocoder/yahoo.rb
28
28
  lib/graticule/location.rb
29
+ lib/graticule/locations.rb
30
+ lib/graticule/precision.rb
29
31
  lib/graticule/version.rb
30
32
  site/index.html
31
33
  site/plugin.html
@@ -36,6 +38,7 @@ test/fixtures/responses/geocoder_us/unknown.xml
36
38
  test/fixtures/responses/google/badkey.xml
37
39
  test/fixtures/responses/google/limit.xml
38
40
  test/fixtures/responses/google/missing_address.xml
41
+ test/fixtures/responses/google/multiple.xml
39
42
  test/fixtures/responses/google/only_coordinates.xml
40
43
  test/fixtures/responses/google/partial.xml
41
44
  test/fixtures/responses/google/server_error.xml
@@ -56,12 +59,14 @@ test/fixtures/responses/postcode_anywhere/canada.xml
56
59
  test/fixtures/responses/postcode_anywhere/empty.xml
57
60
  test/fixtures/responses/postcode_anywhere/success.xml
58
61
  test/fixtures/responses/postcode_anywhere/uk.xml
62
+ test/fixtures/responses/yahoo/multiple.xml
59
63
  test/fixtures/responses/yahoo/success.xml
60
64
  test/fixtures/responses/yahoo/unknown_address.xml
61
65
  test/mocks/uri.rb
62
66
  test/test_helper.rb
63
67
  test/unit/graticule/distance_test.rb
64
68
  test/unit/graticule/geocoder/geocoder_us_test.rb
69
+ test/unit/graticule/geocoder/geocoders.rb
65
70
  test/unit/graticule/geocoder/google_test.rb
66
71
  test/unit/graticule/geocoder/host_ip_test.rb
67
72
  test/unit/graticule/geocoder/local_search_maps_test.rb
@@ -0,0 +1,108 @@
1
+ require "english/levenshtein"
2
+
3
+ module Graticule
4
+ class Locations < Array
5
+ attr :options
6
+
7
+ def best_match(options, &comparator)
8
+ @options = options
9
+ comparator ||= default_comparator
10
+
11
+ max(&comparator)
12
+ end
13
+
14
+ private
15
+
16
+ def default_comparator
17
+ Proc.new do |a, b|
18
+ compare = 0
19
+
20
+ # If an original location object was passed in, compare our results to
21
+ # that in an attempt to find the best match.
22
+ if(options[:original])
23
+ # Always prefer the result matches our original country.
24
+ unless(options[:original].country.blank?)
25
+ if(a.normalized_country == options[:original].normalized_country)
26
+ if(b.normalized_country != options[:original].normalized_country)
27
+ compare = 1
28
+ end
29
+ else
30
+ if(b.normalized_country == options[:original].normalized_country)
31
+ compare = -1
32
+ end
33
+ end
34
+ end
35
+
36
+ # If one of the results has come up with a result outside the
37
+ # starting state, it's probably wrong, so we'll always prefer the
38
+ # other result.
39
+ if(compare == 0)
40
+ unless(options[:original].region.blank?)
41
+ if(a.normalized_region == options[:original].normalized_region)
42
+ if(b.normalized_region != options[:original].normalized_region)
43
+ compare = 1
44
+ end
45
+ else
46
+ if(b.normalized_region == options[:original].normalized_region)
47
+ compare = -1
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ # If the states match, then we'll try to find the best match based on
54
+ # the rest of the data. Since the rest of the items are subject to
55
+ # minor changes that might not be bad (more specific city,
56
+ # alternately named street address, etc), we'll perform some voodoo
57
+ # to see which result is most similar to our original address. We're
58
+ # basically checking which result has the fewest character changes
59
+ # within the strings.
60
+ if(compare == 0)
61
+ # Come up with the character distance for the normalized addresses
62
+ # for each location we're comparing to the original location.
63
+ distance = {}
64
+ { :a => a, :b => b }.each do |key, obj|
65
+ distance[key] = 0
66
+
67
+ unless(options[:original].locality.blank?)
68
+ distance[key] += English::Levenshtein.distance(options[:original].normalized_locality, obj.normalized_locality)
69
+ end
70
+
71
+ unless(options[:original].street.blank?)
72
+ street = if(obj.normalized_street.blank?) then obj.normalized_premise else obj.normalized_street end
73
+ distance[key] += English::Levenshtein.distance(options[:original].normalized_street, street)
74
+ end
75
+
76
+ unless(options[:original].postal_code.blank?)
77
+ distance[key] += English::Levenshtein.distance(options[:original].postal_code_base, obj.postal_code_base)
78
+ end
79
+ end
80
+
81
+ # Pick the object whose normalized address is the most similar
82
+ # character-wise to the original address.
83
+ if(distance[:a] < distance[:b])
84
+ compare = 1
85
+ elsif(distance[:a] > distance[:b])
86
+ compare = -1
87
+ end
88
+ end
89
+ end
90
+
91
+ # If things are still equal at this point, we'll then prefer the result
92
+ # with the higher precision.
93
+ if(compare == 0)
94
+ compare = a.precision <=> b.precision
95
+ end
96
+
97
+ # And if we still don't have a verdict, we'll use the result of which
98
+ # ever geocoder we prefer (in our case, Google, since that's what our
99
+ # maps will be shown on).
100
+ if(compare == 0)
101
+ compare = a.geocoder <=> b.geocoder
102
+ end
103
+
104
+ compare
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,52 @@
1
+ module Graticule
2
+ class Precision
3
+ include Comparable
4
+
5
+ attr_reader :order, :name
6
+
7
+ def initialize(order, name)
8
+ @order = order
9
+ @name = name
10
+ end
11
+
12
+ def <=>(other)
13
+ order <=> other.order
14
+ end
15
+
16
+ def to_s
17
+ @name
18
+ end
19
+
20
+ def self.unknown
21
+ @@unknown ||= Precision.new(0, "unknown")
22
+ end
23
+
24
+ def self.country
25
+ @@country ||= Precision.new(1, "country")
26
+ end
27
+
28
+ def self.state
29
+ @@state ||= Precision.new(2, "state")
30
+ end
31
+
32
+ def self.city
33
+ @@city ||= Precision.new(3, "city")
34
+ end
35
+
36
+ def self.zip
37
+ @@zip ||= Precision.new(4, "zip")
38
+ end
39
+
40
+ def self.street
41
+ @@street ||= Precision.new(5, "street")
42
+ end
43
+
44
+ def self.address
45
+ @@address ||= Precision.new(6, "address")
46
+ end
47
+
48
+ def self.premise
49
+ @@premise ||= Precision.new(7, "premise")
50
+ end
51
+ end
52
+ end
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>gardiner</name><Status><code>200</code><request>geocode</request></Status><Placemark id="p1"><address>Gardiner, ME, USA</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>ME</AdministrativeAreaName><Locality><LocalityName>Gardiner</LocalityName></Locality></AdministrativeArea></Country></AddressDetails><Point><coordinates>-69.802949,44.198024,0</coordinates></Point></Placemark><Placemark id="p2"><address>Gardiner, NY, USA</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>NY</AdministrativeAreaName><Locality><LocalityName>Gardiner</LocalityName></Locality></AdministrativeArea></Country></AddressDetails><Point><coordinates>-74.150462,41.679737,0</coordinates></Point></Placemark><Placemark id="p3"><address>Gardiner, Mt, USA</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>Mt</AdministrativeAreaName><Locality><LocalityName>Gardiner</LocalityName></Locality></AdministrativeArea></Country></AddressDetails><Point><coordinates>-110.705881,45.031672,0</coordinates></Point></Placemark><Placemark id="p4"><address>Gardiner, ME, USA</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>ME</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Kennebec</SubAdministrativeAreaName><Locality><LocalityName>Gardiner</LocalityName></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><Point><coordinates>-69.803716,44.195982,0</coordinates></Point></Placemark><Placemark id="p5"><address>Gardiner, NY, USA</address><AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><AdministrativeArea><AdministrativeAreaName>NY</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Ulster</SubAdministrativeAreaName><Locality><LocalityName>Gardiner</LocalityName></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><Point><coordinates>-74.150462,41.679737,0</coordinates></Point></Placemark></Response></kml>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0"?>
2
+ <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:yahoo:maps" xsi:schemaLocation="urn:yahoo:maps http://api.local.yahoo.com/MapsService/V1/GeocodeResponse.xsd"><Result precision="zip"><Latitude>44.229180</Latitude><Longitude>-69.774749</Longitude><Address></Address><City>Gardiner</City><State>ME</State><Zip></Zip><Country>US</Country></Result><Result precision="zip"><Latitude>45.032793</Latitude><Longitude>-110.705543</Longitude><Address></Address><City>Gardiner</City><State>MT</State><Zip></Zip><Country>US</Country></Result><Result precision="zip"><Latitude>41.679944</Latitude><Longitude>-74.151021</Longitude><Address></Address><City>Gardiner</City><State>NY</State><Zip></Zip><Country>US</Country></Result><Result precision="zip"><Latitude>43.729115</Latitude><Longitude>-124.111529</Longitude><Address></Address><City>Gardiner</City><State>OR</State><Zip></Zip><Country>US</Country></Result></ResultSet>
3
+ <!-- ws03.search.scd.yahoo.com uncompressed/chunked Thu Jun 5 14:53:30 PDT 2008 -->
@@ -0,0 +1,56 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+
4
+ module Graticule
5
+
6
+ # Generic tests for all geocoders (theoretically)
7
+ module GeocodersTestCase
8
+
9
+ def test_success
10
+ return unless prepare_response(:success)
11
+
12
+ location = Location.new(
13
+ :street => "1600 Amphitheatre Pkwy",
14
+ :city => "Mountain View",
15
+ :state => "CA",
16
+ :zip => "94043",
17
+ :country => "US",
18
+ :longitude => -122.083739,
19
+ :latitude => 37.423021,
20
+ :precision => :address
21
+ )
22
+ assert_equal location, @geocoder.locate('1600 Amphitheatre Parkway, Mountain View, CA')
23
+ end
24
+
25
+ def test_bad_key
26
+ return unless prepare_response(:badkey)
27
+ assert_raises(CredentialsError) { @geocoder.locate('x') }
28
+ end
29
+
30
+ def test_locate_missing_address
31
+ return unless prepare_response(:missing_address)
32
+ assert_raises(AddressError) { @geocoder.locate 'x' }
33
+ end
34
+
35
+ def test_locate_server_error
36
+ return unless prepare_response(:server_error)
37
+ assert_raises(Error) { @geocoder.locate 'x' }
38
+ end
39
+
40
+ def test_locate_too_many_queries
41
+ return unless prepare_response(:limit)
42
+ assert_raises(CredentialsError) { @geocoder.locate 'x' }
43
+ end
44
+
45
+ def test_locate_unavailable_address
46
+ return unless prepare_response(:unavailable)
47
+ assert_raises(AddressError) { @geocoder.locate 'x' }
48
+ end
49
+
50
+ def test_locate_unknown_address
51
+ return unless prepare_response(:unknown_address)
52
+ assert_raises(AddressError) { @geocoder.locate 'x' }
53
+ end
54
+
55
+ end
56
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: GUI-graticule
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7.2
4
+ version: 0.2.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Keepers
@@ -72,6 +72,8 @@ files:
72
72
  - lib/graticule/geocoder/rest.rb
73
73
  - lib/graticule/geocoder/yahoo.rb
74
74
  - lib/graticule/location.rb
75
+ - lib/graticule/locations.rb
76
+ - lib/graticule/precision.rb
75
77
  - lib/graticule/version.rb
76
78
  - site/index.html
77
79
  - site/plugin.html
@@ -82,6 +84,7 @@ files:
82
84
  - test/fixtures/responses/google/badkey.xml
83
85
  - test/fixtures/responses/google/limit.xml
84
86
  - test/fixtures/responses/google/missing_address.xml
87
+ - test/fixtures/responses/google/multiple.xml
85
88
  - test/fixtures/responses/google/only_coordinates.xml
86
89
  - test/fixtures/responses/google/partial.xml
87
90
  - test/fixtures/responses/google/server_error.xml
@@ -102,12 +105,14 @@ files:
102
105
  - test/fixtures/responses/postcode_anywhere/empty.xml
103
106
  - test/fixtures/responses/postcode_anywhere/success.xml
104
107
  - test/fixtures/responses/postcode_anywhere/uk.xml
108
+ - test/fixtures/responses/yahoo/multiple.xml
105
109
  - test/fixtures/responses/yahoo/success.xml
106
110
  - test/fixtures/responses/yahoo/unknown_address.xml
107
111
  - test/mocks/uri.rb
108
112
  - test/test_helper.rb
109
113
  - test/unit/graticule/distance_test.rb
110
114
  - test/unit/graticule/geocoder/geocoder_us_test.rb
115
+ - test/unit/graticule/geocoder/geocoders.rb
111
116
  - test/unit/graticule/geocoder/google_test.rb
112
117
  - test/unit/graticule/geocoder/host_ip_test.rb
113
118
  - test/unit/graticule/geocoder/local_search_maps_test.rb