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 +4 -0
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/geocoder.rb +43 -56
- data/rails-geocoder.gemspec +3 -3
- metadata +12 -5
data/CHANGELOG.rdoc
CHANGED
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.
|
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 => "*,
|
99
|
-
|
100
|
-
"
|
101
|
-
|
102
|
-
|
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 =>
|
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
|
-
|
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 =>
|
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
|
##
|
data/rails-geocoder.gemspec
CHANGED
@@ -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
|
+
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
|
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.
|
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
|
-
|
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
|
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.
|
71
|
+
rubygems_version: 1.3.6
|
65
72
|
signing_key:
|
66
73
|
specification_version: 3
|
67
74
|
summary: Add geocoding functionality to Rails models.
|