ppe-georuby 1.7.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.
Files changed (71) hide show
  1. data/.gitignore +6 -0
  2. data/History.txt +4 -0
  3. data/LICENSE +21 -0
  4. data/README.txt +118 -0
  5. data/Rakefile +48 -0
  6. data/VERSION +1 -0
  7. data/lib/geo_ruby.rb +22 -0
  8. data/lib/geo_ruby/gpx.rb +1 -0
  9. data/lib/geo_ruby/gpx4r/gpx.rb +117 -0
  10. data/lib/geo_ruby/shp.rb +1 -0
  11. data/lib/geo_ruby/shp4r/dbf.rb +41 -0
  12. data/lib/geo_ruby/shp4r/shp.rb +697 -0
  13. data/lib/geo_ruby/simple_features/envelope.rb +167 -0
  14. data/lib/geo_ruby/simple_features/ewkb_parser.rb +216 -0
  15. data/lib/geo_ruby/simple_features/ewkt_parser.rb +336 -0
  16. data/lib/geo_ruby/simple_features/geometry.rb +228 -0
  17. data/lib/geo_ruby/simple_features/geometry_collection.rb +136 -0
  18. data/lib/geo_ruby/simple_features/geometry_factory.rb +81 -0
  19. data/lib/geo_ruby/simple_features/georss_parser.rb +135 -0
  20. data/lib/geo_ruby/simple_features/helper.rb +18 -0
  21. data/lib/geo_ruby/simple_features/line_string.rb +206 -0
  22. data/lib/geo_ruby/simple_features/linear_ring.rb +12 -0
  23. data/lib/geo_ruby/simple_features/multi_line_string.rb +51 -0
  24. data/lib/geo_ruby/simple_features/multi_point.rb +46 -0
  25. data/lib/geo_ruby/simple_features/multi_polygon.rb +52 -0
  26. data/lib/geo_ruby/simple_features/point.rb +364 -0
  27. data/lib/geo_ruby/simple_features/polygon.rb +157 -0
  28. data/ppe-georuby.gemspec +133 -0
  29. data/script/console +10 -0
  30. data/script/destroy +14 -0
  31. data/script/generate +14 -0
  32. data/script/txt2html +82 -0
  33. data/spec/data/gpx/fells_loop.gpx +1077 -0
  34. data/spec/data/gpx/long.gpx +1642 -0
  35. data/spec/data/gpx/long.kml +31590 -0
  36. data/spec/data/gpx/long.nmea +2220 -0
  37. data/spec/data/gpx/short.gpx +13634 -0
  38. data/spec/data/gpx/short.kml +130 -0
  39. data/spec/data/gpx/tracktreks.gpx +706 -0
  40. data/spec/data/multipoint.dbf +0 -0
  41. data/spec/data/multipoint.shp +0 -0
  42. data/spec/data/multipoint.shx +0 -0
  43. data/spec/data/point.dbf +0 -0
  44. data/spec/data/point.shp +0 -0
  45. data/spec/data/point.shx +0 -0
  46. data/spec/data/polygon.dbf +0 -0
  47. data/spec/data/polygon.shp +0 -0
  48. data/spec/data/polygon.shx +0 -0
  49. data/spec/data/polyline.dbf +0 -0
  50. data/spec/data/polyline.shp +0 -0
  51. data/spec/data/polyline.shx +0 -0
  52. data/spec/geo_ruby/gpx4r/gpx_spec.rb +106 -0
  53. data/spec/geo_ruby/shp4r/shp_spec.rb +240 -0
  54. data/spec/geo_ruby/simple_features/envelope_spec.rb +45 -0
  55. data/spec/geo_ruby/simple_features/ewkb_parser_spec.rb +158 -0
  56. data/spec/geo_ruby/simple_features/ewkt_parser_spec.rb +179 -0
  57. data/spec/geo_ruby/simple_features/geometry_collection_spec.rb +55 -0
  58. data/spec/geo_ruby/simple_features/geometry_factory_spec.rb +11 -0
  59. data/spec/geo_ruby/simple_features/geometry_spec.rb +32 -0
  60. data/spec/geo_ruby/simple_features/georss_parser_spec.rb +218 -0
  61. data/spec/geo_ruby/simple_features/line_string_spec.rb +245 -0
  62. data/spec/geo_ruby/simple_features/linear_ring_spec.rb +14 -0
  63. data/spec/geo_ruby/simple_features/multi_line_string_spec.rb +54 -0
  64. data/spec/geo_ruby/simple_features/multi_point_spec.rb +35 -0
  65. data/spec/geo_ruby/simple_features/multi_polygon_spec.rb +50 -0
  66. data/spec/geo_ruby/simple_features/point_spec.rb +356 -0
  67. data/spec/geo_ruby/simple_features/polygon_spec.rb +108 -0
  68. data/spec/geo_ruby_spec.rb +27 -0
  69. data/spec/spec.opts +6 -0
  70. data/spec/spec_helper.rb +65 -0
  71. metadata +162 -0
@@ -0,0 +1,245 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ module LineSpecHelper
4
+ def mock_points(num)
5
+ # @point = mock(Point, :x => 1.0, :y => 2.0)
6
+ Array.new(num) { |i| mock_point(i,i) }
7
+ end
8
+
9
+ def mock_point(x=1,y=2)
10
+ mock(Point, :x => x, :y => y, :text_representation => "#{x} #{y}")
11
+ end
12
+ end
13
+
14
+ describe LineString do
15
+ include LineSpecHelper
16
+
17
+ before(:each) do
18
+ @line = LineString.from_points([mock(Point)])
19
+ end
20
+
21
+ it "should instantiate" do
22
+ violated unless @line
23
+ end
24
+
25
+ it "should have binary_geometry_type 2" do
26
+ @line.binary_geometry_type.should eql(2)
27
+ end
28
+
29
+ it "should have text_geometry_type" do
30
+ @line.text_geometry_type.should eql("LINESTRING")
31
+ end
32
+
33
+ it "should have a points array" do
34
+ @line.points.should be_instance_of(Array)
35
+ end
36
+
37
+ describe "tu converted" do
38
+
39
+ it "should concat points" do
40
+ line_string = LineString::new
41
+ line_string.concat([Point.from_x_y(12.4,45.3),Point.from_x_y(45.4,41.6)])
42
+
43
+ line_string.length.should eql(2)
44
+ line_string[0].should == Point.from_x_y(12.4,45.3)
45
+
46
+ point=Point.from_x_y(123,45.8777)
47
+ line_string[0]=point
48
+ line_string[0].should == point
49
+
50
+ points=[Point.from_x_y(123,45.8777),Point.from_x_y(45.4,41.6)]
51
+ line_string.each_index {|i| line_string[i].should == points[i] }
52
+
53
+ point=Point.from_x_y(22.4,13.56)
54
+ line_string << point
55
+ line_string.length.should eql(3)
56
+ line_string[2].should eql(point)
57
+ end
58
+
59
+ it "should create" do
60
+ line_string = LineString.from_points([Point.from_x_y(12.4,-45.3),Point.from_x_y(45.4,41.6)],123)
61
+ line_string.class.should eql(LineString)
62
+ line_string.length.should eql(2)
63
+ line_string[0].should == Point.from_x_y(12.4,-45.3)
64
+ line_string[1].should == Point.from_x_y(45.4,41.6)
65
+
66
+ line_string = LineString.from_coordinates([[12.4,-45.3],[45.4,41.6],[4.456,1.0698]],123)
67
+ line_string.class.should eql(LineString)
68
+ line_string.length.should eql(3)
69
+ line_string[0].should == Point.from_x_y(12.4,-45.3)
70
+ line_string[1].should == Point.from_x_y(45.4,41.6)
71
+
72
+ line_string = LineString.from_coordinates([[12.4,-45.3,123],[45.4,41.6,333],[4.456,1.0698,987]],123,true)
73
+ line_string.class.should eql(LineString)
74
+ line_string.length.should eql(3)
75
+ line_string[0].should == Point.from_x_y_z(12.4,-45.3,123,123)
76
+
77
+ line_string = LineString.from_coordinates([[12.4,-45.3,123],[45.4,41.6,333],[4.456,1.0698,987]],123,true)
78
+ line_string.class.should eql(LineString)
79
+ line_string.length.should eql(3)
80
+ line_string[0].should == Point.from_x_y_z(12.4,-45.3,123,123)
81
+ end
82
+
83
+ it "should bbox it" do
84
+ bbox = LineString.from_coordinates([[12.4,-45.3,123],[45.4,41.6,333],[4.456,1.0698,987]],123,true).bounding_box
85
+ bbox.length.should eql(2)
86
+ bbox[0].should == Point.from_x_y_z(4.456,-45.3,123)
87
+ bbox[1].should == Point.from_x_y_z(45.4,41.6,987)
88
+ end
89
+
90
+ it "should test_line_string_equal" do
91
+ line_string1 = LineString.from_coordinates([[12.4,-45.3],[45.4,41.6],[4.456,1.0698]],123)
92
+ line_string2 = LineString.from_coordinates([[12.4,-45.3],[45.4,41.6]],123)
93
+ point = Point.from_x_y(12.4,-45.3,123)
94
+
95
+ line_string1.should == LineString.from_coordinates([[12.4,-45.3],[45.4,41.6],[4.456,1.0698]],123)
96
+ line_string1.should_not == line_string2
97
+ line_string1.should_not == point
98
+ end
99
+
100
+ it "should test_line_string_binary" do
101
+ line_string = LineString.from_coordinates([[12.4,-45.3],[45.4,41.6]],256)
102
+ line_string.as_hex_ewkb.should eql("01020000200001000002000000CDCCCCCCCCCC28406666666666A646C03333333333B34640CDCCCCCCCCCC4440")
103
+
104
+ line_string = LineString.from_coordinates([[12.4,-45.3,35.3],[45.4,41.6,12.3]],256,true)
105
+ line_string.as_hex_ewkb.should eql("01020000A00001000002000000CDCCCCCCCCCC28406666666666A646C06666666666A641403333333333B34640CDCCCCCCCCCC44409A99999999992840")
106
+
107
+ line_string = LineString.from_coordinates([[12.4,-45.3,35.3,45.1],[45.4,41.6,12.3,40.23]],256,true,true)
108
+ line_string.as_hex_ewkb.should eql("01020000E00001000002000000CDCCCCCCCCCC28406666666666A646C06666666666A64140CDCCCCCCCC8C46403333333333B34640CDCCCCCCCCCC44409A999999999928403D0AD7A3701D4440")
109
+ end
110
+
111
+ it "test_line_string_text" do
112
+ line_string = LineString.from_coordinates([[12.4,-45.3],[45.4,41.6]],256)
113
+ line_string.as_ewkt.should eql("SRID=256;LINESTRING(12.4 -45.3,45.4 41.6)")
114
+
115
+ line_string = LineString.from_coordinates([[12.4,-45.3,35.3],[45.4,41.6,12.3]],256,true)
116
+ line_string.as_ewkt.should eql("SRID=256;LINESTRING(12.4 -45.3 35.3,45.4 41.6 12.3)")
117
+
118
+ line_string = LineString.from_coordinates([[12.4,-45.3,35.3],[45.4,41.6,12.3]],256,false,true)
119
+ line_string.as_ewkt.should eql("SRID=256;LINESTRINGM(12.4 -45.3 35.3,45.4 41.6 12.3)")
120
+
121
+ line_string = LineString.from_coordinates([[12.4,-45.3,35.3,25.2],[45.4,41.6,12.3,13.75]],256,true,true)
122
+ line_string.as_ewkt.should eql("SRID=256;LINESTRING(12.4 -45.3 35.3 25.2,45.4 41.6 12.3 13.75)")
123
+ end
124
+
125
+ it "should test_linear_ring_creation" do
126
+ #testing just the constructor helpers since the rest is the same as for line_string
127
+ linear_ring = LinearRing.from_coordinates([[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],345)
128
+ linear_ring.class.should eql(LinearRing)
129
+ linear_ring.length.should eql(4)
130
+ linear_ring.should be_closed
131
+ linear_ring[1].should == Point.from_x_y(45.4,41.6,345)
132
+ end
133
+ end
134
+
135
+ describe "> Coordinates" do
136
+
137
+ before(:each) do
138
+ Point.should_receive(:from_coordinates).
139
+ exactly(4).with(anything, 4326, false, false).and_return(mock_point)
140
+ @line = LineString.from_coordinates([1.2,2.5,2.2,4.5])
141
+ end
142
+
143
+ it "should instantiate from coordinates" do
144
+ @line.points.length.should eql(4)
145
+ end
146
+
147
+ end
148
+
149
+ describe "> Instantiated" do
150
+
151
+ before(:each) do
152
+ @line = LineString.from_points(mock_points(7))
153
+ end
154
+
155
+ it "should be closed if the last point equals the first" do
156
+ @line.push(@line.first)
157
+ @line.should be_closed
158
+ @line.length.should eql(8)
159
+ end
160
+
161
+ it "should print the text representation" do
162
+ @line.text_representation.should eql("0 0,1 1,2 2,3 3,4 4,5 5,6 6")
163
+ end
164
+
165
+ it "should print the georss_simple_representation" do
166
+ @line.georss_simple_representation({:geom_attr => nil}).
167
+ should eql("<georss:line>0 0 1 1 2 2 3 3 4 4 5 5 6 6</georss:line>\n")
168
+ end
169
+
170
+ it "should map the georss_poslist" do
171
+ @line.georss_poslist.should eql("0 0 1 1 2 2 3 3 4 4 5 5 6 6")
172
+ end
173
+
174
+ it "should print the kml_representation" do
175
+ @line.kml_representation.should
176
+ eql("<LineString>\n<coordinates>0,0 1,1 2,2 3,3 4,4 5,5 6,6</coordinates>\n</LineString>\n")
177
+ end
178
+
179
+ it "should print the kml_poslist without reverse or z" do
180
+ @line.kml_poslist({}).should eql("0,0 1,1 2,2 3,3 4,4 5,5 6,6")
181
+ end
182
+
183
+ it "should print the kml_poslist reverse" do
184
+ @line.kml_poslist({:reverse => true}).should eql("6,6 5,5 4,4 3,3 2,2 1,1 0,0")
185
+ end
186
+ end
187
+
188
+ describe "> Distances..." do
189
+ before(:each) do
190
+ @p1 = mock(Point)
191
+ @p2 = mock(Point)
192
+ @p3 = mock(Point)
193
+ @line = LineString.from_points([@p1,@p2,@p3])
194
+ end
195
+
196
+ it "should print the length with haversine" do
197
+ @p1.should_receive(:spherical_distance).with(@p2).and_return(10)
198
+ @p2.should_receive(:spherical_distance).with(@p3).and_return(10)
199
+ @line.spherical_distance.should eql(20)
200
+ end
201
+
202
+ it "should print lenght as euclidian" do
203
+ @p1.should_receive(:euclidian_distance).with(@p2).and_return(10)
204
+ @p2.should_receive(:euclidian_distance).with(@p3).and_return(10)
205
+ @line.euclidian_distance.should eql(20)
206
+ end
207
+ end
208
+
209
+ describe "Simplify" do
210
+
211
+ before do
212
+ @line = LineString.from_coordinates([[6,0],[4,1],[3,4],[4,6],[5,8],[5,9],[4,10],[6,15]], 4326)
213
+ end
214
+
215
+ it "should simplify a simple linestring" do
216
+ line = LineString.from_coordinates([[12,15],[14,17],[17, 20]], 4326)
217
+ line.simplify.should have(2).points
218
+ end
219
+
220
+ it "should simplify a harder linestring" do
221
+ @line.simplify(6).should have(6).points
222
+ @line.simplify(9).should have(4).points
223
+ @line.simplify(10).should have(3).points
224
+ end
225
+
226
+ it "should barely touch it" do
227
+ @line.simplify(1).should have(7).points
228
+ end
229
+
230
+ it "should simplify to five points" do
231
+ @line.simplify(7).should have(5).points
232
+ end
233
+
234
+ it "should flatten it" do
235
+ @line.simplify(11).should have(2).points
236
+ end
237
+
238
+ it "should be the first and last in a flatten" do
239
+ line = @line.simplify(11)
240
+ line[0].should be_a_point(6, 0)
241
+ line[1].should be_a_point(6, 15)
242
+ end
243
+
244
+ end
245
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe LinearRing do
4
+ # before(:each) do
5
+ # @po = Polygon.new
6
+ # end
7
+
8
+ it "should instantiate" do
9
+ lr = LinearRing.new([1.2,2.5,2.2,4.5])
10
+ lr.should be_instance_of(LinearRing)
11
+ end
12
+
13
+
14
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe MultiLineString do
4
+
5
+ it "test_multi_line_string_creation" do
6
+ multi_line_string1 = MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]],256),LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012],[45.123,123.3]],256)],256)
7
+ multi_line_string1.should be_instance_of(MultiLineString)
8
+ multi_line_string1.length.should eql(2)
9
+ multi_line_string1[0].should == LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]],256)
10
+
11
+ multi_line_string2= MultiLineString.from_coordinates([[[1.5,45.2],[-54.12312,-0.012]],[[1.5,45.2],[-54.12312,-0.012],[45.123,123.3]]],256);
12
+ multi_line_string1.should be_instance_of(MultiLineString)
13
+ multi_line_string1.length.should eql(2)
14
+ multi_line_string2[0].should == LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]],256)
15
+
16
+ multi_line_string2.should == multi_line_string2
17
+ end
18
+
19
+ it "test_multi_line_string_binary" do
20
+ multi_line_string = MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]],256),LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012],[45.123,123.3]],256)],256)
21
+ multi_line_string.as_hex_ewkb.should eql("01050000200001000002000000010200000002000000000000000000F83F9A99999999994640E4BD6A65C20F4BC0FA7E6ABC749388BF010200000003000000000000000000F83F9A99999999994640E4BD6A65C20F4BC0FA7E6ABC749388BF39B4C876BE8F46403333333333D35E40")
22
+
23
+ multi_line_string = MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2,1.3,1.2],[-54.12312,-0.012,1.2,4.5]],256,true,true),LineString.from_coordinates([[1.5,45.2,5.1,-4.5],[-54.12312,-0.012,-6.8,3.4],[45.123,123.3,4.5,-5.3]],256,true,true)],256,true,true)
24
+ multi_line_string.as_hex_ewkb.should eql("0105000020000100000200000001020000C002000000000000000000F83F9A99999999994640CDCCCCCCCCCCF43F333333333333F33FE4BD6A65C20F4BC0FA7E6ABC749388BF333333333333F33F000000000000124001020000C003000000000000000000F83F9A99999999994640666666666666144000000000000012C0E4BD6A65C20F4BC0FA7E6ABC749388BF3333333333331BC03333333333330B4039B4C876BE8F46403333333333D35E40000000000000124033333333333315C0")
25
+ end
26
+
27
+ it "test_multi_line_string_text" do
28
+ multi_line_string = MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]],256),LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012],[45.123,123.3]],256)],256)
29
+ multi_line_string.as_ewkt.should eql("SRID=256;MULTILINESTRING((1.5 45.2,-54.12312 -0.012),(1.5 45.2,-54.12312 -0.012,45.123 123.3))")
30
+
31
+ multi_line_string = MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2,1.3,1.2],[-54.12312,-0.012,1.2,4.5]],256,true,true),LineString.from_coordinates([[1.5,45.2,5.1,-4.5],[-54.12312,-0.012,-6.8,3.4],[45.123,123.3,4.5,-5.3]],256,true,true)],256,true,true)
32
+ multi_line_string.as_ewkt.should eql("SRID=256;MULTILINESTRING((1.5 45.2 1.3 1.2,-54.12312 -0.012 1.2 4.5),(1.5 45.2 5.1 -4.5,-54.12312 -0.012 -6.8 3.4,45.123 123.3 4.5 -5.3))")
33
+ end
34
+
35
+ describe "Some More" do
36
+ before do
37
+ @mls = MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]],256),LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012],[45.123,123.3]],256)],256)
38
+ end
39
+
40
+ it "should have a accessor to all points" do
41
+ @mls.points.should be_instance_of(Array)
42
+ end
43
+
44
+ it "should flatten the array" do
45
+ @mls.should have(5).points
46
+ end
47
+
48
+ it "should simplify to linestring" do
49
+ ls = @mls.to_line_string
50
+ ls.should be_instance_of(LineString)
51
+ ls.should have(5).points
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe MultiPoint do
4
+
5
+ it "test_multi_point_creation" do
6
+ multi_point = MultiPoint.from_coordinates([[12.4,-123.3],[-65.1,123.4],[123.55555555,123]],444)
7
+ multi_point.should be_instance_of(MultiPoint)
8
+ multi_point.length.should eql(3)
9
+ multi_point[0].should == Point.from_x_y(12.4,-123.3,444)
10
+ multi_point[2].should == Point.from_x_y(123.55555555,123,444)
11
+ end
12
+
13
+ it "test_multi_point_binary" do
14
+ multi_point = MultiPoint.from_coordinates([[12.4,-123.3],[-65.1,123.4],[123.55555555,123]],444)
15
+ multi_point.as_hex_ewkb.should eql("0104000020BC010000030000000101000000CDCCCCCCCCCC28403333333333D35EC0010100000066666666664650C09A99999999D95E4001010000001F97DD388EE35E400000000000C05E40")
16
+
17
+ multi_point = MultiPoint.from_coordinates([[12.4,-123.3,4.5],[-65.1,123.4,1.2],[123.55555555,123,2.3]],444,true)
18
+ multi_point.as_hex_ewkb.should eql("01040000A0BC010000030000000101000080CDCCCCCCCCCC28403333333333D35EC00000000000001240010100008066666666664650C09A99999999D95E40333333333333F33F01010000801F97DD388EE35E400000000000C05E406666666666660240")
19
+ end
20
+
21
+ it "test_multi_point_text" do
22
+ multi_point = MultiPoint.from_coordinates([[12.4,-123.3],[-65.1,123.4],[123.55555555,123]],444)
23
+ multi_point.as_ewkt.should eql("SRID=444;MULTIPOINT((12.4 -123.3),(-65.1 123.4),(123.55555555 123))")
24
+
25
+ multi_point = MultiPoint.from_coordinates([[12.4,-123.3,4.5],[-65.1,123.4,6.7],[123.55555555,123,7.8]],444,true)
26
+ multi_point.as_ewkt.should eql("SRID=444;MULTIPOINT((12.4 -123.3 4.5),(-65.1 123.4 6.7),(123.55555555 123 7.8))")
27
+ end
28
+
29
+ it "should respond to points" do
30
+ mp = MultiPoint.from_coordinates([[12.4,-123.3],[-65.1,123.4],[123.55555555,123]],444)
31
+ mp.should have(3).geometries
32
+ mp.should have(3).points
33
+ end
34
+
35
+ end
@@ -0,0 +1,50 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe MultiPolygon do
4
+
5
+ it "test_multi_polygon_creation" do
6
+ multi_polygon1 = MultiPolygon.from_polygons([Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],256),Polygon.from_coordinates([[[0,0],[4,0],[4,4],[0,4],[0,0]],[[1,1],[3,1],[3,3],[1,3],[1,1]]],256)],256)
7
+ multi_polygon1.should be_instance_of(MultiPolygon)
8
+ multi_polygon1.length.should eql(2)
9
+ multi_polygon1[0].should == Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],256)
10
+
11
+ multi_polygon2 = MultiPolygon.from_coordinates([[[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],[[[0,0],[4,0],[4,4],[0,4],[0,0]],[[1,1],[3,1],[3,3],[1,3],[1,1]]]],256)
12
+ multi_polygon1.should be_instance_of(MultiPolygon)
13
+ multi_polygon1.length.should eql(2)
14
+
15
+ multi_polygon2[0].should == Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],256)
16
+ multi_polygon1.should == multi_polygon2
17
+ end
18
+
19
+ it "test_multi_polygon_binary" do
20
+ multi_polygon = MultiPolygon.from_polygons([Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],256),Polygon.from_coordinates([[[0,0],[4,0],[4,4],[0,4],[0,0]],[[1,1],[3,1],[3,3],[1,3],[1,1]]],256)],256)
21
+ multi_polygon.as_hex_ewkb.should eql("0106000020000100000200000001030000000200000004000000CDCCCCCCCCCC28406666666666A646C03333333333B34640CDCCCCCCCCCC44406DE7FBA9F1D211403D2CD49AE61DF13FCDCCCCCCCCCC28406666666666A646C004000000333333333333034033333333333315409A999999999915408A8EE4F21FD2F63FEC51B81E85EB2C40F6285C8FC2F5F03F3333333333330340333333333333154001030000000200000005000000000000000000000000000000000000000000000000001040000000000000000000000000000010400000000000001040000000000000000000000000000010400000000000000000000000000000000005000000000000000000F03F000000000000F03F0000000000000840000000000000F03F00000000000008400000000000000840000000000000F03F0000000000000840000000000000F03F000000000000F03F")
22
+
23
+ multi_polygon = MultiPolygon.from_polygons([Polygon.from_coordinates([[[12.4,-45.3,1.2],[45.4,41.6,1.2],[4.456,1.0698,1.2],[12.4,-45.3,1.2]],[[2.4,5.3,1.2],[5.4,1.4263,1.2],[14.46,1.06,1.2],[2.4,5.3,1.2]]],256,false,true),Polygon.from_coordinates([[[0,0,1.2],[4,0,1.2],[4,4,2.3],[0,4,1.2],[0,0,1.2]],[[1,1,2.2],[3,1,3.3],[3,3,1.1],[1,3,2.4],[1,1,2.2]]],256,false,true)],256,false,true)
24
+ multi_polygon.as_hex_ewkb.should eql("0106000020000100000200000001030000400200000004000000CDCCCCCCCCCC28406666666666A646C0333333333333F33F3333333333B34640CDCCCCCCCCCC4440333333333333F33F6DE7FBA9F1D211403D2CD49AE61DF13F333333333333F33FCDCCCCCCCCCC28406666666666A646C0333333333333F33F0400000033333333333303403333333333331540333333333333F33F9A999999999915408A8EE4F21FD2F63F333333333333F33FEC51B81E85EB2C40F6285C8FC2F5F03F333333333333F33F33333333333303403333333333331540333333333333F33F0103000040020000000500000000000000000000000000000000000000333333333333F33F00000000000010400000000000000000333333333333F33F00000000000010400000000000001040666666666666024000000000000000000000000000001040333333333333F33F00000000000000000000000000000000333333333333F33F05000000000000000000F03F000000000000F03F9A999999999901400000000000000840000000000000F03F6666666666660A40000000000000084000000000000008409A9999999999F13F000000000000F03F00000000000008403333333333330340000000000000F03F000000000000F03F9A99999999990140")
25
+ end
26
+
27
+ it "test_multi_polygon_text" do
28
+ multi_polygon = MultiPolygon.from_polygons([Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],256),Polygon.from_coordinates([[[0,0],[4,0],[4,4],[0,4],[0,0]],[[1,1],[3,1],[3,3],[1,3],[1,1]]],256)],256)
29
+ multi_polygon.as_ewkt.should eql("SRID=256;MULTIPOLYGON(((12.4 -45.3,45.4 41.6,4.456 1.0698,12.4 -45.3),(2.4 5.3,5.4 1.4263,14.46 1.06,2.4 5.3)),((0 0,4 0,4 4,0 4,0 0),(1 1,3 1,3 3,1 3,1 1)))")
30
+
31
+ multi_polygon = MultiPolygon.from_polygons([Polygon.from_coordinates([[[12.4,-45.3,2],[45.4,41.6,3],[4.456,1.0698,4],[12.4,-45.3,2]],[[2.4,5.3,1],[5.4,1.4263,3.44],[14.46,1.06,4.5],[2.4,5.3,1]]],4326,true),Polygon.from_coordinates([[[0,0,5.6],[4,0,5.4],[4,4,1],[0,4,23],[0,0,5.6]],[[1,1,2.3],[3,1,4],[3,3,5],[1,3,6],[1,1,2.3]]],4326,true)],4326,true)
32
+ multi_polygon.as_ewkt.should eql("SRID=4326;MULTIPOLYGON(((12.4 -45.3 2,45.4 41.6 3,4.456 1.0698 4,12.4 -45.3 2),(2.4 5.3 1,5.4 1.4263 3.44,14.46 1.06 4.5,2.4 5.3 1)),((0 0 5.6,4 0 5.4,4 4 1,0 4 23,0 0 5.6),(1 1 2.3,3 1 4,3 3 5,1 3 6,1 1 2.3)))")
33
+ end
34
+
35
+ describe "Counting" do
36
+
37
+ before do
38
+ @mp = MultiPolygon.from_polygons([Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],256),Polygon.from_coordinates([[[0,0],[4,0],[4,4],[0,4],[0,0]],[[1,1],[3,1],[3,3],[1,3],[1,1]]],256)],256)
39
+ end
40
+
41
+ it "should have a points method" do
42
+ @mp.points[0].should be_instance_of(Point)
43
+ end
44
+
45
+ it "should flatten it right" do
46
+ @mp.should have(18).points
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,356 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
+
4
+ describe Point do
5
+ before(:each) do
6
+ @point = Point.new(4326)
7
+ end
8
+
9
+ it "should instantiatember" do
10
+ violated unless @point
11
+ @point.should be_instance_of(Point)
12
+ end
13
+
14
+ it "should have a nice matcher" do
15
+ @point.should be_a_point
16
+ end
17
+
18
+ it "should have a very nice matcher" do
19
+ @point.should be_a_point(0.0, 0.0)
20
+ end
21
+
22
+ it "should have a very nice matcher" do
23
+ Point.from_x_y_z_m(1,2,3.33,"t").should be_a_point(1, 2, 3.33, "t")
24
+ end
25
+
26
+ it "should have a dumb matcher" do
27
+ Point.should be_geometric
28
+ end
29
+
30
+ it "should be subclassable" do
31
+ place = Class.new(Point)
32
+ p = place.from_x_y(1,2)
33
+ p.should be_a place
34
+ end
35
+
36
+ it "should have binary_geometry_type 2" do
37
+ @point.binary_geometry_type.should eql(1)
38
+ end
39
+
40
+ it "should have the correct srid" do
41
+ @point.srid.should eql(4326)
42
+ end
43
+
44
+ it "should not have z or m" do
45
+ @point.with_z.should be_false
46
+ @point.should_not be_with_z
47
+ @point.with_m.should be_false
48
+ @point.should_not be_with_m
49
+ end
50
+
51
+ it "should set params to 0.0" do
52
+ @point.x.should eql(0.0)
53
+ @point.y.should eql(0.0)
54
+ @point.z.should eql(0.0)
55
+ @point.m.should eql(0.0)
56
+ end
57
+
58
+ it "should compare ok" do
59
+ point1= Point::new
60
+ point1.set_x_y(1.5,45.4)
61
+ point2= Point::new
62
+ point2.set_x_y(1.5,45.4)
63
+ point3= Point::new
64
+ point3.set_x_y(4.5,12.3)
65
+ point4= Point::new
66
+ point4.set_x_y_z(1.5,45.4,423)
67
+ point5= Point::new
68
+ point5.set_x_y(1.5,45.4)
69
+ point5.m=15
70
+ geometry= Geometry::new
71
+
72
+ point1.should == point2
73
+ point1.should_not == point3
74
+ point1.should_not == point4
75
+ point1.should_not == point5
76
+ point1.should_not == geometry
77
+ end
78
+
79
+ describe "> Instantiation" do
80
+
81
+ it "should instantiate a 2d point" do
82
+ point = Point.from_x_y(10,20,123)
83
+ point.x.should eql(10)
84
+ point.y.should eql(20)
85
+ point.srid.should eql(123)
86
+ point.z.should eql(0.0)
87
+ end
88
+
89
+ it "should instantiate a 3d point" do
90
+ point = Point.from_x_y_z(-10,-20,-30)
91
+ point.x.should eql(-10)
92
+ point.y.should eql(-20)
93
+ point.z.should eql(-30)
94
+ end
95
+
96
+ it "should instantiate a 3d(m) point" do
97
+ point = Point.from_x_y_m(10,20,30)
98
+ point.x.should eql(10)
99
+ point.y.should eql(20)
100
+ point.m.should eql(30)
101
+ point.z.should eql(0.0)
102
+ end
103
+
104
+ it "should instantiate a 4d point" do
105
+ point = Point.from_x_y_z_m(10,20,30,40,123)
106
+ point.x.should eql(10)
107
+ point.y.should eql(20)
108
+ point.z.should eql(30)
109
+ point.m.should eql(40)
110
+ point.srid.should eql(123)
111
+ end
112
+
113
+ it "should instantiate a point from polar coordinates" do
114
+ point = Point.from_r_t(1.4142,45)
115
+ point.y.should be_close(1, 0.00001)
116
+ point.x.should be_close(1, 0.00001)
117
+ end
118
+
119
+ it "should instantiate from coordinates x,y" do
120
+ point = Point.from_coordinates([1.6,2.8],123)
121
+ point.x.should eql(1.6)
122
+ point.y.should eql(2.8)
123
+ point.should_not be_with_z
124
+ point.z.should eql(0.0)
125
+ point.srid.should eql(123)
126
+ end
127
+
128
+ it "should instantiate from coordinates x,y,z" do
129
+ point = Point.from_coordinates([1.6,2.8,3.4],123, true)
130
+ point.x.should eql(1.6)
131
+ point.y.should eql(2.8)
132
+ point.z.should eql(3.4)
133
+ point.should be_with_z
134
+ point.srid.should eql(123)
135
+ end
136
+
137
+ it "should instantiate from coordinates x,y,z,m" do
138
+ point = Point.from_coordinates([1.6,2.8,3.4,15],123, true, true)
139
+ point.x.should eql(1.6)
140
+ point.y.should eql(2.8)
141
+ point.z.should eql(3.4)
142
+ point.m.should eql(15)
143
+ point.should be_with_z
144
+ point.should be_with_m
145
+ point.srid.should eql(123)
146
+ end
147
+
148
+ it "should have a bbox" do
149
+ bbox = Point.from_x_y_z_m(-1.6,2.8,-3.4,15,123).bounding_box
150
+ bbox.length.should eql(2)
151
+ bbox[0].should == Point.from_x_y_z(-1.6,2.8,-3.4)
152
+ bbox[1].should == Point.from_x_y_z(-1.6,2.8,-3.4)
153
+ end
154
+
155
+ it "should parse lat long" do
156
+ Point.from_latlong("-20° 47' 26.37","-20° 47' 26.37").x.should be_close(-20.790658, 0.00001)
157
+ Point.from_latlong("20° 47' 26.378","20° 47' 26.378").y.should be_close(20.790658, 0.00001)
158
+ end
159
+
160
+ it "should parse lat long w/o sec" do
161
+ Point.from_latlong("-20°47′26″","-20°47′26″").x.should be_close(-20.790555, 0.00001)
162
+ Point.from_latlong("20°47′26″","20°47′26″").y.should be_close(20.790555, 0.00001)
163
+ end
164
+
165
+ it "should accept with W or S notation" do
166
+ Point.from_latlong("20° 47' 26.37 W","20° 47' 26.37 S").x.should be_close(-20.790658, 0.00001)
167
+ Point.from_latlong("20° 47' 26.37 W","20° 47' 26.37 S").y.should be_close(-20.790658, 0.00001)
168
+ end
169
+
170
+ it "should instantiate a point from positive degrees" do
171
+ point = Point.from_latlong('47`20 06.09E','22`50 77.35N')
172
+ point.y.should be_close(22.8548194, 0.000001)
173
+ point.x.should be_close(47.335025, 0.000001)
174
+ end
175
+
176
+ it "should instantiate a point from negative degrees" do
177
+ point = Point.from_latlong('47`20 06.09W','22`50 77.35S')
178
+ point.y.should be_close(-22.8548194, 0.000001)
179
+ point.x.should be_close(-47.335025, 0.000001)
180
+ end
181
+
182
+ it "should print out nicely" do
183
+ Point.from_x_y(47.88, -20.1).as_latlong.should eql("47°52′48″, -20°06′00″")
184
+ end
185
+
186
+ it "should print out nicely" do
187
+ Point.from_x_y(-20.78, 20.78).as_latlong(:full => true).should eql("-20°46′48.00″, 20°46′48.00″")
188
+ end
189
+
190
+ it "should print out nicely" do
191
+ Point.from_x_y(47.11, -20.2).as_latlong(:full => true).should eql("47°06′36.00″, -20°11′60.00″")
192
+ end
193
+
194
+ it "should print out nicely" do
195
+ Point.from_x_y(47.11, -20.2).as_latlong(:coord => true).should eql("47°06′36″N, 20°11′60″W")
196
+ end
197
+
198
+ it "should print out nicely" do
199
+ Point.from_x_y(-47.11, 20.2).as_latlong(:full => true,:coord => true).should eql("47°06′36.00″S, 20°11′60.00″E")
200
+ end
201
+
202
+ end
203
+
204
+ describe " > Distance & Bearing" do
205
+
206
+ before(:each) do
207
+ @p1 = Point.from_x_y(1,1)
208
+ @p2 = Point.from_x_y(2,2)
209
+ end
210
+
211
+ it "and a 3th grade child should calculate euclidian distance" do
212
+ @p1.euclidian_distance(@p2).
213
+ should be_close(1.4142135623731, 0.00000001)
214
+ end
215
+
216
+ it "should calculate spherical distance" do
217
+ @p1.spherical_distance(@p2).
218
+ should be_close(157225.358003181,0.00000001)
219
+ end
220
+
221
+ it "should calculate ellipsoidal distance" do
222
+ @p1.ellipsoidal_distance(@p2).
223
+ should be_close(156876.149400742, 0.00000001)
224
+ end
225
+
226
+ describe "Orthogonal Distance" do
227
+ before do
228
+ @line = LineString.from_coordinates([[0,0],[1,3]], 4326)
229
+ @line2 = LineString.from_coordinates([[1,1],[1,2]], 4326)
230
+ end
231
+
232
+ it "should calcula orthogonal distance from a line (90 deg)" do
233
+ @p1.orthogonal_distance(@line).should be_close(1.414, 0.001)
234
+ end
235
+
236
+ it "should calcula orthogonal distance very close..." do
237
+ @p1.orthogonal_distance(@line2).should be_zero
238
+ end
239
+
240
+ it "should calcula orthogonal distance from a line (90 deg)" do
241
+ @p2.orthogonal_distance(@line).should be_close(2.828, 0.001)
242
+ end
243
+
244
+ it "should calcula orthogonal distance from a line (0 deg)" do
245
+ @p2.orthogonal_distance(@line2).should be_close(1.0, 0.1)
246
+ end
247
+
248
+ it "should calcula orthogonal distance from a line (0 deg)" do
249
+ @p2.orthogonal_distance(@line2).should be_close(1.0, 0.1)
250
+ end
251
+
252
+ end
253
+
254
+ it "should calculate the bearing from apoint to another in degrees" do
255
+ @p1.bearing_to(@p2).should be_close(45.0, 0.01)
256
+ end
257
+
258
+ it "should calculate the bearing from apoint to another in degrees" do
259
+ p3 = Point.from_x_y(1,-1)
260
+ @p1.bearing_to(p3).should be_close(180.0, 0.01)
261
+ end
262
+
263
+ it "should calculate the bearing from apoint to another in degrees" do
264
+ p3 = Point.from_x_y(-1,-1)
265
+ @p1.bearing_to(p3).should be_close(225.0, 0.01)
266
+ end
267
+
268
+ it "should calculate the bearing from apoint to another in degrees" do
269
+ p3 = Point.from_x_y(-1,1)
270
+ @p1.bearing_to(p3).should be_close(270.0, 0.01)
271
+ end
272
+
273
+ it "should calculate the bearing from apoint to another in degrees" do
274
+ p3 = Point.from_x_y(2,-1)
275
+ @p1.bearing_to(p3).should be_close(153.4349488, 0.0001)
276
+ end
277
+
278
+ it "should calculate a clone point bearing to 0" do
279
+ @p1.bearing_to(@p1).should eql(0)
280
+ end
281
+
282
+ it "should calculate the bearing from apoint to another in degrees" do
283
+ @p1.bearing_text(@p2).should eql(:ne)
284
+ end
285
+
286
+ it "should calculate the bearing from apoint to another in degrees" do
287
+ p3 = Point.from_x_y(-1,1)
288
+ @p1.bearing_text(p3).should eql(:w)
289
+ end
290
+
291
+ end
292
+
293
+ describe "> Export Formats" do
294
+
295
+ before(:each) do
296
+ @point = Point.from_x_y( -11.2431, 32.3141 )
297
+ end
298
+
299
+ it "should print nicely" do
300
+ @point.text_representation.should eql("-11.2431 32.3141")
301
+ end
302
+
303
+ it "should printoout as binary" do
304
+ Point.from_x_y(12.4,45.3,123).as_hex_ewkb.should eql("01010000207B000000CDCCCCCCCCCC28406666666666A64640")
305
+ point = Point.from_x_y_z_m(12.4,45.3,-3.5,15,123)
306
+ point.as_hex_ewkb.should eql("01010000E07B000000CDCCCCCCCCCC28406666666666A646400000000000000CC00000000000002E40")
307
+ point.as_hex_wkb.should eql("0101000000CDCCCCCCCCCC28406666666666A64640")
308
+ end
309
+
310
+ it "should printoout as text" do
311
+ Point.from_x_y(12.4,45.3,123).as_ewkt.should eql("SRID=123;POINT(12.4 45.3)")
312
+ point = Point.from_x_y_z(12.4,45.3,-3.5,123)
313
+ point.as_ewkt.should eql("SRID=123;POINT(12.4 45.3 -3.5)")
314
+ point.as_wkt.should eql("POINT(12.4 45.3)")
315
+ point.as_ewkt(false,true).should eql("POINT(12.4 45.3 -3.5)")
316
+ point = Point.from_x_y_m(12.4,45.3,-3.5,123)
317
+ point.as_ewkt.should eql("SRID=123;POINTM(12.4 45.3 -3.5)")
318
+ point.as_ewkt(true,true,false).should eql("SRID=123;POINT(12.4 45.3)")
319
+ end
320
+
321
+ it "should have a nice bounding box" do
322
+ @point.should have(2).bounding_box
323
+ @point.bounding_box.each do |point|
324
+ point.x.should eql(@point.x)
325
+ point.y.should eql(@point.y)
326
+ end
327
+ end
328
+
329
+ it "should print as kml too" do
330
+ @point.kml_representation.should eql("<Point>\n<coordinates>-11.2431,32.3141</coordinates>\n</Point>\n")
331
+ end
332
+
333
+ it "should print as georss" do
334
+ @point.georss_simple_representation(:georss_ns => 'hey').should eql("<hey:point>32.3141 -11.2431</hey:point>\n")
335
+ end
336
+
337
+ it "should print r (polar coords)" do
338
+ @point.r.should be_close(34.214154, 0.00001)
339
+ end
340
+
341
+ it "should print theta as degrees" do
342
+ @point.theta_deg.should be_close(289.184406352127, 0.0001)
343
+ end
344
+
345
+ it "should print theta as radians" do
346
+ @point.theta_rad.should be_close(5.04722003626982, 0.0001)
347
+ end
348
+
349
+ it "should output as polar" do
350
+ @point.as_polar.should be_instance_of(Array)
351
+ @point.should have(2).as_polar #.length.should eql(2)
352
+ end
353
+
354
+ end
355
+
356
+ end