geo_vectors 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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