rails-geocoder 0.8.9 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Per-release changes to Geocoder.
4
4
 
5
+ == 0.9.0 (2010 Apr 2)
6
+
7
+ * Fix bug in PostgreSQL support (caused "PGError: ERROR: column "distance" does not exist"), reported by developish.
8
+
5
9
  == 0.8.9 (2010 Feb 11)
6
10
 
7
11
  * Add Rails 3 compatibility.
data/README.rdoc CHANGED
@@ -113,7 +113,7 @@ SQLite's lack of trigonometric functions means Geocoder's default implementation
113
113
 
114
114
  There are few options for finding objects near a given point in SQLite without installing extensions:
115
115
 
116
- 1. Use a square instead of a circle for finding nearby points. For example, if you want to find points near 40.71, 100.23, search for objects with latitude between 39.71 and 41.71 and longitude between 99.23 and 101.23. One degree of latitude or longitude is at most 69 miles so divide your radius (in miles) by 69.0 to get the amount to add and subtract from your center coordinates to get the upper and lower bounds. The results will not be very accurate (you'll get points outside the desired radius), but you will get all the points within the required radius.
116
+ 1. Use a square instead of a circle for finding nearby points. For example, if you want to find points near 40.71, 100.23, search for objects with latitude between 39.71 and 41.71 and longitude between 99.23 and 101.23. One degree of latitude or longitude is at most 69 miles so divide your radius (in miles) by 69.0 to get the amount to add and subtract from your center coordinates to get the upper and lower bounds. The results will not be very accurate (you'll get points outside the desired radius--at worst 29% farther away), but you will get all the points within the required radius.
117
117
 
118
118
  2. Load all objects into memory and compute distances between them using the <tt>Geocoder.distance_between</tt> method. This will produce accurate results but will be very slow (and use a lot of memory) if you have a lot of objects in your database.
119
119
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.9
1
+ 0.9.0
data/lib/geocoder.rb CHANGED
@@ -67,47 +67,28 @@ module Geocoder
67
67
  ##
68
68
  # Named scope options hash for use with a database that supports POWER(),
69
69
  # SQRT(), PI(), and trigonometric functions (SIN(), COS(), and ASIN()).
70
- #
70
+ #
71
71
  # Taken from the excellent tutorial at:
72
72
  # http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
73
73
  #
74
74
  def full_near_scope_options(latitude, longitude, radius, options)
75
-
76
- # set defaults/clean up arguments
77
75
  options[:order] ||= 'distance ASC'
78
- radius = radius.to_i
79
-
80
- # constrain search to a (radius x radius) square
81
- factor = (Math::cos(latitude * Math::PI / 180.0) * 69.0).abs
82
- lon_lo = longitude - (radius / factor);
83
- lon_hi = longitude + (radius / factor);
84
- lat_lo = latitude - (radius / 69.0);
85
- lat_hi = latitude + (radius / 69.0);
86
-
87
- # build limit clause
88
- limit = nil
89
- if options[:limit] or options[:offset]
90
- options[:offset] ||= 0
91
- limit = "#{options[:offset]},#{options[:limit]}"
92
- end
93
-
94
- # generate hash
95
76
  lat_attr = geocoder_options[:latitude]
96
77
  lon_attr = geocoder_options[:longitude]
78
+ distance = "3956 * 2 * ASIN(SQRT(" +
79
+ "POWER(SIN((#{latitude} - #{lat_attr}) * " +
80
+ "PI() / 180 / 2), 2) + COS(#{latitude} * PI()/180) * " +
81
+ "COS(#{lat_attr} * PI() / 180) * " +
82
+ "POWER(SIN((#{longitude} - #{lon_attr}) * " +
83
+ "PI() / 180 / 2), 2) ))"
97
84
  {
98
- :select => "*, 3956 * 2 * ASIN(SQRT(" +
99
- "POWER(SIN((#{latitude} - #{lat_attr}) * " +
100
- "PI() / 180 / 2), 2) + COS(#{latitude} * PI()/180) * " +
101
- "COS(#{lat_attr} * PI() / 180) * " +
102
- "POWER(SIN((#{longitude} - #{lon_attr}) * " +
103
- "PI() / 180 / 2), 2) )) as distance",
104
- :conditions => [
105
- "#{lat_attr} BETWEEN ? AND ? AND " +
106
- "#{lon_attr} BETWEEN ? AND ?",
107
- lat_lo, lat_hi, lon_lo, lon_hi],
108
- :having => "distance <= #{radius}",
85
+ :select => "*, #{distance} AS distance",
86
+ :conditions => \
87
+ ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
88
+ coordinate_bounds(latitude, longitude, radius),
89
+ :having => "#{distance} <= #{radius}",
109
90
  :order => options[:order],
110
- :limit => limit
91
+ :limit => limit_clause(options)
111
92
  }
112
93
  end
113
94
 
@@ -118,36 +99,42 @@ module Geocoder
118
99
  # objects outside the given radius).
119
100
  #
120
101
  def approx_near_scope_options(latitude, longitude, radius, options)
121
-
122
- # set defaults/clean up arguments
123
- radius = radius.to_i
124
-
125
- # constrain search to a (radius x radius) square
126
- factor = (Math::cos(latitude * Math::PI / 180.0) * 69.0).abs
127
- lon_lo = longitude - (radius / factor);
128
- lon_hi = longitude + (radius / factor);
129
- lat_lo = latitude - (radius / 69.0);
130
- lat_hi = latitude + (radius / 69.0);
131
-
132
- # build limit clause
133
- limit = nil
134
- if options[:limit] or options[:offset]
135
- options[:offset] ||= 0
136
- limit = "#{options[:offset]},#{options[:limit]}"
137
- end
138
-
139
- # generate hash
140
102
  lat_attr = geocoder_options[:latitude]
141
103
  lon_attr = geocoder_options[:longitude]
142
104
  {
143
- :conditions => [
144
- "#{lat_attr} BETWEEN ? AND ? AND " +
145
- "#{lon_attr} BETWEEN ? AND ?",
146
- lat_lo, lat_hi, lon_lo, lon_hi],
105
+ :conditions => \
106
+ ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
107
+ coordinate_bounds(latitude, longitude, radius),
147
108
  :order => options[:order],
148
- :limit => limit
109
+ :limit => limit_clause(options)
149
110
  }
150
111
  end
112
+
113
+ ##
114
+ # Get the rough high/low lat/long bounds for a geographic point and
115
+ # radius. Returns an array: <tt>[lat_lo, lat_hi, lon_lo, lon_hi]</tt>.
116
+ # Used to constrain search to a (radius x radius) square.
117
+ #
118
+ def coordinate_bounds(latitude, longitude, radius)
119
+ radius = radius.to_f
120
+ factor = (Math::cos(latitude * Math::PI / 180.0) * 69.0).abs
121
+ [
122
+ latitude - (radius / 69.0),
123
+ latitude + (radius / 69.0),
124
+ longitude - (radius / factor),
125
+ longitude + (radius / factor)
126
+ ]
127
+ end
128
+
129
+ ##
130
+ # Build the limit clause for a query based on the same options hash
131
+ # passed to the x_near_scope_options methods.
132
+ #
133
+ def limit_clause(options)
134
+ if options[:limit] or options[:offset]
135
+ "#{options[:offset].to_i},#{options[:limit].to_i}"
136
+ end
137
+ end
151
138
  end
152
139
 
153
140
  ##
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rails-geocoder}
8
- s.version = "0.8.9"
8
+ s.version = "0.9.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Alex Reisner"]
12
- s.date = %q{2010-02-11}
12
+ s.date = %q{2010-04-02}
13
13
  s.description = %q{Geocoder adds object geocoding and database-agnostic distance calculations to Ruby on Rails. It does not rely on proprietary database functions so finding geocoded objects in a given area is easily done using out-of-the-box MySQL or even SQLite.}
14
14
  s.email = %q{alex@alexreisner.com}
15
15
  s.extra_rdoc_files = [
@@ -35,7 +35,7 @@ Gem::Specification.new do |s|
35
35
  s.homepage = %q{http://github.com/alexreisner/geocoder}
36
36
  s.rdoc_options = ["--charset=UTF-8"]
37
37
  s.require_paths = ["lib"]
38
- s.rubygems_version = %q{1.3.5}
38
+ s.rubygems_version = %q{1.3.6}
39
39
  s.summary = %q{Add geocoding functionality to Rails models.}
40
40
  s.test_files = [
41
41
  "test/geocoder_test.rb",
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-geocoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.9
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 9
8
+ - 0
9
+ version: 0.9.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Alex Reisner
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-11 00:00:00 -05:00
17
+ date: 2010-04-02 00:00:00 -04:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -50,18 +55,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
50
55
  requirements:
51
56
  - - ">="
52
57
  - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
53
60
  version: "0"
54
- version:
55
61
  required_rubygems_version: !ruby/object:Gem::Requirement
56
62
  requirements:
57
63
  - - ">="
58
64
  - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
59
67
  version: "0"
60
- version:
61
68
  requirements: []
62
69
 
63
70
  rubyforge_project:
64
- rubygems_version: 1.3.5
71
+ rubygems_version: 1.3.6
65
72
  signing_key:
66
73
  specification_version: 3
67
74
  summary: Add geocoding functionality to Rails models.