geokit-lite 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in geokit-lite.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Todd Eichel
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # GeokitLite
2
+
3
+ A couple methods extracted from Geokit and Geokit Rails
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'geokit-lite'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install geokit-lite
18
+
19
+ ## Usage
20
+
21
+ Check out the inline comments.
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'geokit-lite'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "geokit-lite"
8
+ gem.version = GeokitLite::VERSION
9
+ gem.authors = ["Todd Eichel"]
10
+ gem.email = ["todd@toddeichel.com"]
11
+ gem.description = %q{A couple methods extracted from Geokit and Geokit Rails}
12
+ gem.summary = %q{A couple methods extracted from Geokit and Geokit Rails}
13
+ gem.homepage = "http://github.com/taskrabbit/geokit-lite"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,130 @@
1
+ class GeokitLite
2
+ VERSION = '0.0.1'
3
+
4
+ PI_DIV_RAD = 0.0174
5
+ KMS_PER_MILE = 1.609
6
+ NMS_PER_MILE = 0.868976242
7
+ EARTH_RADIUS_IN_MILES = 3963.19
8
+ EARTH_RADIUS_IN_KMS = EARTH_RADIUS_IN_MILES * KMS_PER_MILE
9
+ EARTH_RADIUS_IN_NMS = EARTH_RADIUS_IN_MILES * NMS_PER_MILE
10
+ MILES_PER_LATITUDE_DEGREE = 69.1
11
+ KMS_PER_LATITUDE_DEGREE = MILES_PER_LATITUDE_DEGREE * KMS_PER_MILE
12
+ NMS_PER_LATITUDE_DEGREE = MILES_PER_LATITUDE_DEGREE * NMS_PER_MILE
13
+ LATITUDE_DEGREES = EARTH_RADIUS_IN_MILES / MILES_PER_LATITUDE_DEGREE
14
+
15
+ DEFAULT_OPTIONS = {
16
+ :units => :miles,
17
+ :formula => :flat,
18
+ :lat_column_name => 'lat',
19
+ :lng_column_name => 'lng'
20
+ }
21
+
22
+ class << self
23
+
24
+ # Returns the distance between two points. The from and to parameters are
25
+ # required to have lat and lng attributes. Valid options are:
26
+ # :units - valid values are :miles, :kms, :nms (Geokit::default_units is the default)
27
+ # :formula - valid values are :flat or :sphere (Geokit::default_formula is the default)
28
+ def distance_between(from, to, opts = {})
29
+ opts.reverse_merge!(DEFAULT_OPTIONS)
30
+
31
+ return 0.0 if from == to # fixes a "zero-distance" bug
32
+ units = opts[:units]
33
+ formula = opts[:formula]
34
+ case formula
35
+ when :sphere
36
+ begin
37
+ units_sphere_multiplier(units) *
38
+ Math.acos( Math.sin(deg2rad(from.first)) * Math.sin(deg2rad(to.first)) +
39
+ Math.cos(deg2rad(from.first)) * Math.cos(deg2rad(to.first)) *
40
+ Math.cos(deg2rad(to.last) - deg2rad(from.last)))
41
+ rescue Errno::EDOM
42
+ 0.0
43
+ end
44
+ when :flat
45
+ Math.sqrt((units_per_latitude_degree(units)*(from.first-to.first))**2 +
46
+ (units_per_longitude_degree(from.first, units)*(from.last-to.last))**2)
47
+ end
48
+ end
49
+
50
+
51
+ # Returns the distance calculation to be used as a display column or a condition. This
52
+ # is provide for anyone wanting access to the raw SQL.
53
+ def distance_sql(lat, lng, opts = {})
54
+ opts.reverse_merge!(DEFAULT_OPTIONS)
55
+
56
+ opts[:qualified_lat_column_name] = [opts[:table_name], opts[:lat_column_name]].compact.join('.')
57
+ opts[:qualified_lng_column_name] = [opts[:table_name], opts[:lng_column_name]].compact.join('.')
58
+
59
+ case opts[:formula]
60
+ when :sphere
61
+ sql = sphere_distance_sql(lat, lng, opts)
62
+ when :flat
63
+ sql = flat_distance_sql(lat, lng, opts)
64
+ end
65
+ sql
66
+ end
67
+
68
+
69
+ protected
70
+
71
+ def sphere_distance_sql(lat, lng, opts)
72
+ lat = deg2rad(lat)
73
+ lng = deg2rad(lng)
74
+ multiplier = units_sphere_multiplier(opts[:units])
75
+
76
+ %|
77
+ (ACOS(least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{opts[:qualified_lat_column_name]}))*COS(RADIANS(#{opts[:qualified_lng_column_name]}))+
78
+ COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{opts[:qualified_lat_column_name]}))*SIN(RADIANS(#{opts[:qualified_lng_column_name]}))+
79
+ SIN(#{lat})*SIN(RADIANS(#{opts[:qualified_lat_column_name]}))))*#{multiplier})
80
+ |
81
+ end
82
+
83
+ def flat_distance_sql(lat, lng, opts)
84
+ lat_degree_units = units_per_latitude_degree(opts[:units])
85
+ lng_degree_units = units_per_longitude_degree(lat, opts[:units])
86
+
87
+ %|
88
+ SQRT(POW(#{lat_degree_units}*(#{lat}-#{opts[:qualified_lat_column_name]}),2)+
89
+ POW(#{lng_degree_units}*(#{lng}-#{opts[:qualified_lng_column_name]}),2))
90
+ |
91
+ end
92
+
93
+ def deg2rad(degrees)
94
+ degrees.to_f / 180.0 * Math::PI
95
+ end
96
+
97
+ def rad2deg(rad)
98
+ rad.to_f * 180.0 / Math::PI
99
+ end
100
+
101
+
102
+ # Returns the multiplier used to obtain the correct distance units.
103
+ def units_sphere_multiplier(units)
104
+ case units
105
+ when :kms; EARTH_RADIUS_IN_KMS
106
+ when :nms; EARTH_RADIUS_IN_NMS
107
+ else EARTH_RADIUS_IN_MILES
108
+ end
109
+ end
110
+
111
+ # Returns the number of units per latitude degree.
112
+ def units_per_latitude_degree(units)
113
+ case units
114
+ when :kms; KMS_PER_LATITUDE_DEGREE
115
+ when :nms; NMS_PER_LATITUDE_DEGREE
116
+ else MILES_PER_LATITUDE_DEGREE
117
+ end
118
+ end
119
+
120
+ # Returns the number units per longitude degree.
121
+ def units_per_longitude_degree(lat, units)
122
+ miles_per_longitude_degree = (LATITUDE_DEGREES * Math.cos(lat * PI_DIV_RAD)).abs
123
+ case units
124
+ when :kms; miles_per_longitude_degree * KMS_PER_MILE
125
+ when :nms; miles_per_longitude_degree * NMS_PER_MILE
126
+ else miles_per_longitude_degree
127
+ end
128
+ end
129
+ end
130
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geokit-lite
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Todd Eichel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-10-29 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: A couple methods extracted from Geokit and Geokit Rails
22
+ email:
23
+ - todd@toddeichel.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .gitignore
32
+ - Gemfile
33
+ - LICENSE.txt
34
+ - README.md
35
+ - Rakefile
36
+ - geokit-lite.gemspec
37
+ - lib/geokit-lite.rb
38
+ homepage: http://github.com/taskrabbit/geokit-lite
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ hash: 3
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.8.5
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: A couple methods extracted from Geokit and Geokit Rails
71
+ test_files: []
72
+