server-side-google-maps 0.1.1 → 0.1.2
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/lib/server-side-google-maps/path.rb +29 -0
- data/lib/server-side-google-maps/point.rb +27 -0
- data/lib/server-side-google-maps/version.rb +1 -1
- data/spec/path_spec.rb +56 -0
- data/spec/point_spec.rb +23 -0
- metadata +3 -3
@@ -77,8 +77,37 @@ module ServerSideGoogleMaps
|
|
77
77
|
ret << create_interpolated_point(points[-1], points[-1], 0.0, :distance_along_path => points[-1].distance_along_path)
|
78
78
|
end
|
79
79
|
|
80
|
+
def simplify(latlng_error2)
|
81
|
+
simplified_points = douglas_peucker_step(points, latlng_error2)
|
82
|
+
Path.new(simplified_points)
|
83
|
+
end
|
84
|
+
|
80
85
|
private
|
81
86
|
|
87
|
+
def douglas_peucker_step(points, latlng_error2)
|
88
|
+
simple_points = [ points.first, points.last ]
|
89
|
+
max_i = 0
|
90
|
+
max_d = 0
|
91
|
+
|
92
|
+
points.each_with_index do |point, i|
|
93
|
+
next if i == 0 || i == points.length - 1
|
94
|
+
d = point.latlng_distance_squared_from_segment(points.first, points.last)
|
95
|
+
if d > max_d
|
96
|
+
max_d = d
|
97
|
+
max_i = i
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
if max_d > latlng_error2
|
102
|
+
simple1 = douglas_peucker_step(points[0..max_i], latlng_error2)
|
103
|
+
simple2 = douglas_peucker_step(points[max_i..-1], latlng_error2)
|
104
|
+
simple1.pop
|
105
|
+
return simple1.concat(simple2)
|
106
|
+
else
|
107
|
+
return simple_points
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
82
111
|
def create_interpolated_point(point_before, point_after, fraction_after, options = {})
|
83
112
|
fraction_before = 1.0 - fraction_after
|
84
113
|
|
@@ -45,5 +45,32 @@ module ServerSideGoogleMaps
|
|
45
45
|
longitude_difference = longitude - other.longitude
|
46
46
|
latitude_difference * latitude_difference + longitude_difference * longitude_difference
|
47
47
|
end
|
48
|
+
|
49
|
+
def latlng_distance_squared_from_segment(p1, p2)
|
50
|
+
vx = p1.latitude - latitude
|
51
|
+
vy = p1.longitude - longitude
|
52
|
+
|
53
|
+
return vx*vx + vy*vy if p1 == p2
|
54
|
+
|
55
|
+
ux = p2.latitude - p1.latitude
|
56
|
+
uy = p2.longitude - p1.longitude
|
57
|
+
length2 = ux*ux + uy*uy
|
58
|
+
|
59
|
+
det = (-vx*ux) + (-vy*uy)
|
60
|
+
|
61
|
+
if det < 0 || det > length2
|
62
|
+
# We're outside the line segment
|
63
|
+
wx = p2.latitude - latitude
|
64
|
+
wy = p2.longitude - longitude
|
65
|
+
|
66
|
+
d1 = vx*vx + vy*vy
|
67
|
+
d2 = wx*wx + wy*wy
|
68
|
+
return d1 < d2 ? d1 : d2
|
69
|
+
end
|
70
|
+
|
71
|
+
det = ux*vy - uy*vx
|
72
|
+
|
73
|
+
return det * det / length2
|
74
|
+
end
|
48
75
|
end
|
49
76
|
end
|
data/spec/path_spec.rb
CHANGED
@@ -116,5 +116,61 @@ module ServerSideGoogleMaps
|
|
116
116
|
interpolated[4].elevation.should == 50
|
117
117
|
end
|
118
118
|
end
|
119
|
+
|
120
|
+
describe('#simplify') do
|
121
|
+
it('should remove duplicate points') do
|
122
|
+
p1 = Point.new(1.0, 2.0)
|
123
|
+
p2 = Point.new(7.0, 2.0)
|
124
|
+
p2_2 = Point.new(7.0, 2.0)
|
125
|
+
p3 = Point.new(7.0, 1.0)
|
126
|
+
|
127
|
+
path = Path.new([p1, p2, p2_2, p3])
|
128
|
+
simplified = path.simplify(0.00001)
|
129
|
+
simplified.points.length.should == 3
|
130
|
+
simplified.points[0].should == p1
|
131
|
+
simplified.points[1].should == p2
|
132
|
+
simplified.points[2].should == p3
|
133
|
+
end
|
134
|
+
|
135
|
+
it('should remove useless points') do
|
136
|
+
p1 = Point.new(1.0, 2.0)
|
137
|
+
p2 = Point.new(6.0, 1.23)
|
138
|
+
p3 = Point.new(7.0, 1.0)
|
139
|
+
|
140
|
+
path = Path.new([p1, p2, p3])
|
141
|
+
simplified = path.simplify(0.005)
|
142
|
+
simplified.points.length.should == 2
|
143
|
+
simplified.points[0].should == p1
|
144
|
+
simplified.points[1].should == p3
|
145
|
+
end
|
146
|
+
|
147
|
+
it('should retain useful points') do
|
148
|
+
p1 = Point.new(1.0, 2.0)
|
149
|
+
p2 = Point.new(6.0, 1.23)
|
150
|
+
p3 = Point.new(7.0, 1.0)
|
151
|
+
|
152
|
+
path = Path.new([p1, p2, p3])
|
153
|
+
simplified = path.simplify(0.0005)
|
154
|
+
simplified.points.length.should == 3
|
155
|
+
simplified.points[0].should == p1
|
156
|
+
simplified.points[1].should == p2
|
157
|
+
end
|
158
|
+
|
159
|
+
it('should retain :distance_along_path, :elevation, :object') do
|
160
|
+
p1 = Point.new(1.0, 2.0, :distance_along_path => 0, :elevation => 0, :object => 0)
|
161
|
+
p2 = Point.new(6.0, 1.23, :distance_along_path => 1, :elevation => 1, :object => 1)
|
162
|
+
p3 = Point.new(7.0, 1.0, :distance_along_path => 2, :elevation => 2, :object => 2)
|
163
|
+
|
164
|
+
path = Path.new([p1, p2, p3])
|
165
|
+
simplified = path.simplify(0.005)
|
166
|
+
simplified.points.length.should == 2
|
167
|
+
simplified.points[0].object.should == p1.object
|
168
|
+
simplified.points[0].distance_along_path.should == p1.distance_along_path
|
169
|
+
simplified.points[0].elevation.should == p1.elevation
|
170
|
+
simplified.points[1].object.should == p3.object
|
171
|
+
simplified.points[1].distance_along_path.should == p3.distance_along_path
|
172
|
+
simplified.points[1].elevation.should == p3.elevation
|
173
|
+
end
|
174
|
+
end
|
119
175
|
end
|
120
176
|
end
|
data/spec/point_spec.rb
CHANGED
@@ -39,6 +39,29 @@ module ServerSideGoogleMaps
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
describe('#latlng_distance_squared_from_segment') do
|
43
|
+
it('should catch when point is outside segment edges') do
|
44
|
+
# p1 ------------*---------
|
45
|
+
# p2 --*------------------- <- this point is farther than it'd be if the
|
46
|
+
# p3 -------------------*-- line segment were an infinite line
|
47
|
+
p1 = Point.new(1.0, 7.0)
|
48
|
+
p2 = Point.new(-1.0, 9.1)
|
49
|
+
p3 = Point.new(7.0, 1.0)
|
50
|
+
|
51
|
+
distance2 = p2.latlng_distance_squared_from_segment(p1, p3)
|
52
|
+
distance2.should == p2.latlng_distance_squared(p1)
|
53
|
+
end
|
54
|
+
|
55
|
+
it('should work when segment is a singularity') do
|
56
|
+
p1 = Point.new(1.0, 7.0)
|
57
|
+
p2 = Point.new(-1.0, 9.1)
|
58
|
+
p3 = Point.new(1.0, 7.0)
|
59
|
+
|
60
|
+
distance2 = p2.latlng_distance_squared_from_segment(p1, p3)
|
61
|
+
distance2.should == p2.latlng_distance_squared(p1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
42
65
|
describe('#distance') do
|
43
66
|
it('should calculate the distance') do
|
44
67
|
point1 = Point.new(1.0, 4.0)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: server-side-google-maps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Hooper
|