geo_vectors 0.5.0

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.
Files changed (47) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Distance calc notes.txt +64 -0
  4. data/Gemfile +14 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.textile +178 -0
  7. data/Rakefile +53 -0
  8. data/VERSION +1 -0
  9. data/geo_vectors.gemspec +115 -0
  10. data/lib/geo_vectors.rb +7 -0
  11. data/lib/geo_vectors/bearing_vector.rb +87 -0
  12. data/lib/geo_vectors/core_ext.rb +54 -0
  13. data/lib/geo_vectors/direction_vector.rb +59 -0
  14. data/lib/geo_vectors/geo_point.rb +33 -0
  15. data/lib/geo_vectors/geo_vector.rb +56 -0
  16. data/lib/geo_vectors/geo_vectors.rb +92 -0
  17. data/lib/geo_vectors/point_vector.rb +85 -0
  18. data/lib/geo_vectors/point_vector/point_ops.rb +23 -0
  19. data/lib/geo_vectors/point_vector/vector_ops.rb +38 -0
  20. data/lib/geo_vectors/util.rb +3 -0
  21. data/lib/geo_vectors/util/calc.rb +89 -0
  22. data/lib/geo_vectors/util/geo_direction.rb +101 -0
  23. data/lib/geo_vectors/util/geo_distance.rb +135 -0
  24. data/lib/geo_vectors/util/geo_units.rb +53 -0
  25. data/lib/geo_vectors/vector_parser.rb +54 -0
  26. data/spec/geo_vectors/API proposal guide.txt +142 -0
  27. data/spec/geo_vectors/bearing_vector/add_vector_spec.rb +30 -0
  28. data/spec/geo_vectors/bearing_vector/random_spec.rb +18 -0
  29. data/spec/geo_vectors/bearing_vector_spec.rb +34 -0
  30. data/spec/geo_vectors/direction_vector/add_vector_spec.rb +30 -0
  31. data/spec/geo_vectors/direction_vector/point_add_spec.rb +0 -0
  32. data/spec/geo_vectors/direction_vector/random_spec.rb +16 -0
  33. data/spec/geo_vectors/direction_vector/subtract_vector_spec.rb +0 -0
  34. data/spec/geo_vectors/direction_vector_spec.rb +27 -0
  35. data/spec/geo_vectors/geo_vectors_spec.rb +108 -0
  36. data/spec/geo_vectors/point_vector/add_vector_spec.rb +135 -0
  37. data/spec/geo_vectors/point_vector/initializer_spec.rb +82 -0
  38. data/spec/geo_vectors/point_vector/point_add_spec.rb +45 -0
  39. data/spec/geo_vectors/point_vector/random_spec.rb +17 -0
  40. data/spec/geo_vectors/point_vector/scale_vector_spec.rb +52 -0
  41. data/spec/geo_vectors/point_vector/subtract_vector_spec.rb +80 -0
  42. data/spec/geo_vectors/point_vector_spec.rb +111 -0
  43. data/spec/geo_vectors/util/geo_direction_spec.rb +74 -0
  44. data/spec/geo_vectors/util/geo_distance_spec.rb +70 -0
  45. data/spec/geo_vectors/util/geo_units_spec.rb +23 -0
  46. data/spec/spec_helper.rb +7 -0
  47. metadata +218 -0
@@ -0,0 +1,135 @@
1
+ # h3. Addition
2
+ #
3
+ # Vectors can be added to form a new Vector, using the simple formula vec = v1 + v2 = (v1.x + v2.y, v1.x + v2.y)
4
+ #
5
+ # h3. Vector on Vector addition
6
+ #
7
+ # If both vectors are point vectors, the result is simply a new point vector
8
+ #
9
+ # <pre>
10
+ # v1 = [1, 3].vector
11
+ # v2 = [-2, 2].vector
12
+ # vec = v1 + v2
13
+ # vec.unit.should == :degrees
14
+ # vec.lat.should == -1
15
+ # vec.lng.should == 5
16
+ #
17
+ # # alternative addition operators
18
+ # vec = v1 << v2
19
+ # </pre>
20
+ #
21
+ # h3. Vector subtraction
22
+ #
23
+ # <pre>
24
+ # v1 = [1, 3].vector
25
+ # v2 = [2, 1].vector
26
+ # vec = v1 - v2 # here v2 inversed (scaled by -1) and then added
27
+ # vec.lat.should == -1
28
+ # vec.lng.should == 2
29
+ # </pre>
30
+ #
31
+
32
+ # h3. Vector scaling
33
+ #
34
+ # <pre>
35
+ # v1 = [1, 3].vector
36
+ # vec = v1 * 2
37
+ # vec.lat.should == 2
38
+ # vec.lng.should == 6
39
+ # </pre>
40
+
41
+ require 'spec_helper'
42
+
43
+ describe PointVector do
44
+ describe 'Vector on Vector Addition' do
45
+ context 'Point vector (4, 2)' do
46
+ describe '#+ operator' do
47
+ let (:vec) { vec = [4, 2].vector }
48
+
49
+ it 'should Add one geo vector' do
50
+ v2 = vec + [1, 2].vector
51
+ v2.lat.should == 5
52
+ v2.lng.should == 4
53
+ end
54
+ end #+
55
+
56
+ # describe '#add! operator' do
57
+ # let (:vec) { vec = [4, 2].vector }
58
+ #
59
+ # it 'should Add one geo vector' do
60
+ # vec.add!([1,2].vector)
61
+ # vec.lng.should == 4
62
+ # vec.lat.should == 5
63
+ # end
64
+ #
65
+ # describe 'converting args to vector' do
66
+ # let (:vec) { vec = [4, 2].vector }
67
+ #
68
+ # it 'should Add after converting number args to geo vector' do
69
+ # vec.add!(1,2)
70
+ # vec.lat.should == 5
71
+ # vec.lng.should == 4
72
+ # end
73
+ #
74
+ # it 'should Add one geo vector' do
75
+ # vec.add!("1,2")
76
+ # vec.lat.should == 5
77
+ # vec.lng.should == 4
78
+ # end
79
+ # end # add!
80
+ # end # point vector
81
+
82
+ describe '#add operator' do
83
+ let (:vec) { vec = [4, 2].vector }
84
+
85
+ it 'should Add one geo vector' do
86
+ v2 = vec.add([1,2].vector)
87
+ v2.lng.should == 4
88
+ v2.lat.should == 5
89
+ end
90
+
91
+ describe 'converting args to vector' do
92
+ let (:vec) { vec = [4, 2].vector }
93
+
94
+ it 'should Add after converting number args to geo vector' do
95
+ v2 = vec.add(1,2)
96
+ v2.lat.should == 5
97
+ v2.lng.should == 4
98
+ end
99
+
100
+ it 'should Add one geo vector' do
101
+ v2 = vec.add("1,2")
102
+ v2.lat.should == 5
103
+ v2.lng.should == 4
104
+ end
105
+ end # add!
106
+ end # point vector
107
+
108
+
109
+ # context 'Bearing vector (60, 2.km)' do
110
+ # let(:vec) { vec = [4, 2].vector }
111
+ # let(:brng_vec) { BearingVector.new 60, 2.km }
112
+ #
113
+ # describe '#add!' do
114
+ # it 'should raise error when applying bearing vector directly on a point vector' do
115
+ # lambda {vec.apply!(brng_vec)}.should raise_error
116
+ # end
117
+ # end
118
+ #
119
+ # describe '#+ (add)' do
120
+ # it 'should add the vector and create a new PointVectors from result' do
121
+ # vectors = vec + brng_vec
122
+ # vectors.should be_a GeoVectors
123
+ # end
124
+ # end
125
+ #
126
+ # describe '#<< (push)' do
127
+ # it 'should add the vector and create a new point from result' do
128
+ # vectors = vec << brng_vec
129
+ # vectors.should be_a GeoVectors
130
+ # end
131
+ # end
132
+ # end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ describe PointVector do
4
+ describe '#initialize' do
5
+ describe 'pure call' do
6
+ it 'should init from an Array' do
7
+ vec = PointVector.new [11.1, 2]
8
+ vec.should be_a(PointVector)
9
+ vec.lat.should == 11.1
10
+ vec.lng.should == 2
11
+ end
12
+
13
+ it 'should init from a Hash' do
14
+ vec = PointVector.new :lat => 11.1, :lon => 2
15
+ vec.should be_a(PointVector)
16
+ vec.lat.should == 11.1
17
+ vec.lng.should == 2
18
+ end
19
+
20
+ it 'should init from a String' do
21
+ vec = PointVector.new "11.1, 2"
22
+ vec.should be_a(PointVector)
23
+ vec.lat.should == 11.1
24
+ vec.lng.should == 2
25
+ end
26
+
27
+ describe 'two args' do
28
+ it 'should init from two Strings' do
29
+ vec = PointVector.new "11.1", "2"
30
+ vec.should be_a(PointVector)
31
+ vec.lat.should == 11.1
32
+ vec.lng.should == 2
33
+ end
34
+
35
+ it 'should init from two numbers' do
36
+ vec = PointVector.new 11.1, 2
37
+ vec.should be_a(PointVector)
38
+ vec.lat.should == 11.1
39
+ vec.lng.should == 2
40
+ end
41
+
42
+ it 'should init from a number and a String' do
43
+ vec = PointVector.new 11.1, "2"
44
+ vec.should be_a(PointVector)
45
+ vec.lat.should == 11.1
46
+ vec.lng.should == 2
47
+ end
48
+ end
49
+ end
50
+
51
+ describe 'factory methods on other class' do
52
+ it 'should init from an Array' do
53
+ vec = [11.1, 2].geo_vector
54
+ vec.should be_a(PointVector)
55
+ vec.lat.should == 11.1
56
+ vec.lng.should == 2
57
+ end
58
+
59
+ it 'should init from a GeoPoint' do
60
+ vec = "11.1, 2".geo_point.geo_vector
61
+ vec.should be_a(PointVector)
62
+ vec.lat.should == 11.1
63
+ vec.lng.should == 2
64
+ end
65
+
66
+ it 'should init from a Hash' do
67
+ vec = {:lat => 11.1, :lon => 2}.geo_vector
68
+ vec.should be_a(PointVector)
69
+ vec.lat.should == 11.1
70
+ vec.lng.should == 2
71
+ end
72
+
73
+ it 'should init from a String' do
74
+ vec = "11.1, 2".geo_vector
75
+ vec.should be_a(PointVector)
76
+ vec.lat.should == 11.1
77
+ vec.lng.should == 2
78
+ end
79
+ end
80
+ end
81
+ end
82
+
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe PointVector do
4
+ describe 'PointAdd module' do
5
+ context 'GeoPoint (3, 5)' do
6
+ let(:point) { GeoPoint.new 3, 5 }
7
+
8
+ context 'Simple vector (1, 2)' do
9
+ let(:vector) { PointVector.new 1, 2 }
10
+
11
+ describe '#add!' do
12
+ before :each do
13
+ @p = GeoPoint.new 3, 5
14
+ end
15
+
16
+ it 'should Add the vector: (1, 2)' do
17
+ @p.add!(vector)
18
+ @p.lat.should == 4
19
+ @p.lng.should == 7
20
+ end
21
+ end
22
+
23
+ describe '#+ (add)' do
24
+ it 'should add the vector (1, 2) and create a new point from result' do
25
+ p2 = point + vector
26
+ point.lat.should == 3 # no change
27
+ point.lng.should == 5
28
+ p2.lat.should == 4 # new point should be result of addition
29
+ p2.lng.should == 7
30
+ end
31
+ end
32
+
33
+ describe '#<< (push)' do
34
+ it 'should add the vector (1, 2) and create a new point from result' do
35
+ p2 = point << vector
36
+ point.lat.should == 3 # no change
37
+ point.lng.should == 5
38
+ p2.lat.should == 4 # new point should be result of addition
39
+ p2.lng.should == 7
40
+ end
41
+ end
42
+ end # context Simple vector
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe GeoVector do
4
+ describe 'Random module' do
5
+ context 'Point vector (4, 2)' do
6
+ describe '#random_vector' do
7
+ let (:vec) { vec = [4, 2].vector }
8
+
9
+ it 'should return a random vector to a point within bounding box' do
10
+ rvec = vec.random_vector
11
+ rvec.lat.should be_between(-4, 4)
12
+ rvec.lng.should be_between(-2, 2)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,52 @@
1
+ # h3. Vector scaling
2
+ #
3
+ # <pre>
4
+ # v1 = [1, 3].vector
5
+ # vec = v1 * 2
6
+ # vec.lat.should == 2
7
+ # vec.lng.should == 6
8
+ # </pre>
9
+
10
+ require 'spec_helper'
11
+
12
+ describe PointVector do
13
+ describe 'Scaling' do
14
+ let (:vec) { [4, 2].geo_vector }
15
+
16
+ describe '#* operator' do
17
+ it 'should scale the vector 2 times bigger (* 2)' do
18
+ v2 = vec * 2
19
+ v2.lat.should == 8
20
+ v2.lng.should == 4
21
+ end
22
+
23
+ it 'should scale the vector to half size (* 0.5)' do
24
+ v2 = vec * 0.5
25
+ v2.lat.should == 2
26
+ v2.lng.should == 1
27
+ end
28
+ end
29
+
30
+ describe '#/ operator' do
31
+ it 'should scale the vector 2 times bigger (/ 0.5)' do
32
+ v2 = vec / 0.5
33
+ v2.lat.should == 8
34
+ v2.lng.should == 4
35
+ end
36
+
37
+ it 'should scale the vector to half size bigger (/ 2)' do
38
+ v2 = vec / 2
39
+ v2.lat.should == 2
40
+ v2.lng.should == 1
41
+ end
42
+ end
43
+
44
+ describe '# scale! operator' do
45
+ it 'should scale the vector 2 times bigger (* 2)' do
46
+ vec.scale!(2)
47
+ vec.lat.should == 8
48
+ vec.lng.should == 4
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,80 @@
1
+ # h3. Addition
2
+ #
3
+ # Vectors can be added to form a new Vector, using the simple formula vec = v1 + v2 = (v1.x + v2.y, v1.x + v2.y)
4
+ #
5
+ # h3. Vector on Vector subtraction
6
+ #
7
+ # h3. Vector subtraction
8
+ #
9
+ # <pre>
10
+ # v1 = [1, 3].vector
11
+ # v2 = [2, 1].vector
12
+ # vec = v1 - v2 # here v2 inversed (scaled by -1) and then added
13
+ # vec.lat.should == -1
14
+ # vec.lng.should == 2
15
+ # </pre>
16
+ #
17
+
18
+ # h3. Vector scaling
19
+ #
20
+ # <pre>
21
+ # v1 = [1, 3].vector
22
+ # vec = v1 * 2
23
+ # vec.lat.should == 2
24
+ # vec.lng.should == 6
25
+ # </pre>
26
+
27
+ require 'spec_helper'
28
+
29
+ describe GeoVector do
30
+ describe 'Vector on Vector Subtraction' do
31
+ describe '#- operator' do
32
+ let (:vec) { vec = [4, 3].vector }
33
+
34
+ it 'should Subtract one geo vector' do
35
+ v = [1, 2].vector
36
+ v2 = vec - v
37
+ v2.should_not == vec
38
+ v2.lat.should == 3
39
+ v2.lng.should == 1
40
+ end
41
+ end
42
+
43
+ describe '#sub operator (alias for -)' do
44
+ let (:vec) { vec = [4, 3].vector }
45
+
46
+ it 'should Subtract one geo vector' do
47
+ v = [1, 2].vector
48
+ v2 = vec.sub(v)
49
+ v2.should_not == vec
50
+ v2.lat.should == 3
51
+ v2.lng.should == 1
52
+ end
53
+ end
54
+
55
+ describe '#sub! operator' do
56
+ let (:vec) { vec = [4, 3].vector }
57
+
58
+ it 'should Subtract one geo vector' do
59
+ v2 = vec.sub!([1,2].vector)
60
+ v2.should == vec
61
+ vec.lat.should == 3
62
+ vec.lng.should == 1
63
+ end
64
+
65
+ describe 'converting args to vector' do
66
+ it 'should Subtract after converting number args to geo vector' do
67
+ vec.sub!(1,2)
68
+ vec.lat.should == 3
69
+ vec.lng.should == 1
70
+ end
71
+
72
+ it 'should Subtract one geo vector' do
73
+ vec.sub!("1,2")
74
+ vec.lat.should == 3
75
+ vec.lng.should == 1
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe PointVector do
4
+ describe '#initialize' do
5
+ it 'should initialize from an Array' do
6
+ vec = [1, 2].point_vector
7
+ vec.should be_a PointVector
8
+ end
9
+
10
+ it 'should set origin at 0,0' do
11
+ origin = [0, 0].geo_point
12
+ origin.lat.should == 0
13
+ origin.lng.should == 0
14
+ end
15
+ end
16
+
17
+ context 'Simple vector at (1, 2) - x,y arg' do
18
+ let(:vector) { PointVector.new 1, 2 }
19
+
20
+ it 'should create a PointVector: x=1, y=1' do
21
+ vector.should be_a PointVector
22
+ vector.y.should == 1
23
+ vector.x.should == 2
24
+ end
25
+
26
+ it 'should create a vector: lat=1, lng=1' do
27
+ vector.lat.should == 1
28
+ vector.lng.should == 2
29
+ end
30
+
31
+ it 'should create a vector: latitude=1, longitude=1' do
32
+ vector.latitude.should == 1
33
+ vector.longitude.should == 2
34
+ end
35
+ end
36
+
37
+ context 'Simple vector at (1, 2) - Array arg' do
38
+ let(:vector) { PointVector.new [1, 2] }
39
+
40
+ it 'should create a vector: x=1, y=2' do
41
+ vector.y.should == 1
42
+ vector.x.should == 2
43
+ end
44
+ end
45
+
46
+ context 'Vectors from points: p1 = (1,2) ; p2 = (4,6) ' do
47
+ before do
48
+ @p1 = GeoPoint.new 1,2
49
+ @p2 = GeoPoint.new 4,6
50
+ end
51
+
52
+ it 'should create a vector between the points p1 and p2' do
53
+ @vec = PointVector.new @p1, @p2
54
+ @vec.y.should == 3
55
+ @vec.x.should == 4
56
+ end
57
+ end
58
+
59
+ pending 'TODO' do
60
+ context 'Simple vector at (1, 2) and a direction vector' do
61
+ before do
62
+ @p1 = GeoPoint.new 1,2
63
+ @east_4 = DirectionVector.new 4.km, :east
64
+ end
65
+
66
+ it 'should create a vector between a point and a new point generated from applying the direction to the point' do
67
+ @vec = PointVector.new @p1, @east_4
68
+ @vec.x.should == 1
69
+ @vec.y.should == 6
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'Simple vector at (1, 2) - GeoPoint arg' do
75
+ let(:vector) { PointVector.new [1, 2].to_point }
76
+
77
+ describe '#length' do
78
+ it 'should have a distance between 240 - 250 km' do
79
+ kms = vector.length
80
+ kms.should be_between(240, 250)
81
+ end
82
+ end
83
+
84
+ describe '#distance' do
85
+ it 'should have a distance between 240 - 250 km' do
86
+ dist = vector.distance
87
+ dist.should be_a GeoDistance
88
+ dist.in_meters.should be_between(240000, 250000)
89
+ end
90
+ end
91
+
92
+ describe '#point=' do
93
+ before do
94
+ @vec = PointVector.new [1, 2].to_point
95
+ end
96
+
97
+ it 'should set a new vector point of 2,3' do
98
+ @vec.y.should == 1
99
+ @vec.x.should == 2
100
+ @vec.point = 2, 3
101
+ @vec.y.should == 2
102
+ @vec.x.should == 3
103
+ end
104
+
105
+ it 'should return a new distance between 240 - 250' do
106
+ kms = @vec.distance.in_kms
107
+ kms.should be_between(240, 250)
108
+ end
109
+ end
110
+ end
111
+ end