georuby-ext 0.0.1 → 0.0.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 (51) hide show
  1. data/.jrubyrc +1 -0
  2. data/.travis.yml +23 -0
  3. data/Gemfile +6 -0
  4. data/Guardfile +12 -2
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +2 -28
  7. data/georuby-ext.gemspec +14 -11
  8. data/lib/georuby-ext.rb +17 -2
  9. data/lib/georuby-ext/core_ext.rb +11 -0
  10. data/lib/georuby-ext/geokit.rb +10 -3
  11. data/lib/georuby-ext/georuby/envelope.rb +36 -1
  12. data/lib/georuby-ext/georuby/ewkb_parser.rb +11 -0
  13. data/lib/georuby-ext/georuby/ewkt_parser.rb +11 -0
  14. data/lib/georuby-ext/georuby/geometry.rb +46 -2
  15. data/lib/georuby-ext/georuby/line_string.rb +19 -7
  16. data/lib/georuby-ext/georuby/linear_ring.rb +15 -0
  17. data/lib/georuby-ext/georuby/locators.rb +30 -17
  18. data/lib/georuby-ext/georuby/multi_polygon.rb +15 -1
  19. data/lib/georuby-ext/georuby/point.rb +148 -24
  20. data/lib/georuby-ext/georuby/polygon.rb +38 -27
  21. data/lib/georuby-ext/georuby/rtree.rb +133 -0
  22. data/lib/georuby-ext/georuby/srid.rb +17 -0
  23. data/lib/georuby-ext/proj4.rb +15 -2
  24. data/lib/georuby-ext/rgeo/cartesian/feature_methods.rb +58 -0
  25. data/lib/georuby-ext/rgeo/feature/geometry.rb +11 -0
  26. data/lib/georuby-ext/rgeo/feature/geometry_collection.rb +11 -0
  27. data/lib/georuby-ext/rgeo/feature/rgeo.rb +157 -0
  28. data/lib/georuby-ext/rgeo/geos/ffi_feature_methods.rb +265 -0
  29. data/lib/georuby-ext/rspec_helper.rb +47 -8
  30. data/spec/lib/geokit_spec.rb +44 -0
  31. data/spec/lib/georuby/envelope_spec.rb +46 -0
  32. data/spec/lib/georuby/geometry_spec.rb +81 -0
  33. data/spec/{georuby → lib/georuby}/line_string_spec.rb +29 -14
  34. data/spec/lib/georuby/linear_ring_spec.rb +52 -0
  35. data/spec/lib/georuby/locators_spec.rb +123 -0
  36. data/spec/lib/georuby/multi_polygon_spec.rb +69 -0
  37. data/spec/lib/georuby/point_spec.rb +248 -0
  38. data/spec/lib/georuby/polygon_spec.rb +175 -0
  39. data/spec/lib/georuby/rtree_spec.rb +132 -0
  40. data/spec/lib/proj4_spec.rb +24 -0
  41. data/spec/lib/rgeo/cartesian/feature_methods_spec.rb +110 -0
  42. data/spec/lib/rgeo/geos/ffi_feature_methods_spec.rb +234 -0
  43. data/spec/spec_helper.rb +12 -8
  44. metadata +224 -189
  45. data/lib/georuby-ext/rgeo.rb +0 -23
  46. data/spec/georuby/linear_ring_spec.rb +0 -33
  47. data/spec/georuby/locators_spec.rb +0 -120
  48. data/spec/georuby/multi_polygon_spec.rb +0 -29
  49. data/spec/georuby/point_spec.rb +0 -44
  50. data/spec/georuby/polygon_spec.rb +0 -134
  51. data/spec/rgeo_spec.rb +0 -81
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+
3
+ describe GeoRuby::SimpleFeatures::MultiPolygon do
4
+
5
+ describe "#to_wgs84" do
6
+ let(:multi_polygon_google) { geometry "MULTIPOLYGON(((0.0 -7.08115455161362e-10,0.0 111325.142866385,111319.490793272 -7.08115455161362e-10,0.0 -7.08115455161362e-10)))", 900913 }
7
+ let(:multi_polygon_wgs84) { geometry "MULTIPOLYGON(((0 0,0 1,1 0,0 0)))" }
8
+
9
+ it "should return a polygon in wgs84 coordinates" do
10
+ [multi_polygon_google.to_wgs84.points, multi_polygon_wgs84.points].transpose.each{ |p1,p2|
11
+ p1.x.should be_within(0.0000001).of(p2.x)
12
+ p1.y.should be_within(0.0000001).of(p2.y)
13
+ }
14
+ end
15
+
16
+ it "should return a multi_polygon with wgs84 srid" do
17
+ multi_polygon_google.to_wgs84.srid.should == multi_polygon_wgs84.srid
18
+ end
19
+ end
20
+
21
+ describe "#polygons" do
22
+ let(:geo_multi_polygon) { geometry "MULTIPOLYGON(((0 0,0 1,1 1,1 0)), ((0 0,0 1,1 1,1 0)))" }
23
+ let(:geo_polygon){ polygon("(0 0,0 1,1 1,1 0)") }
24
+
25
+ it "should return an array of polygons" do
26
+ geo_multi_polygon.polygons.should == [geo_polygon, geo_polygon]
27
+ end
28
+ end
29
+
30
+ describe "#difference" do
31
+ let(:g_multi_polygon) { geometry("MULTIPOLYGON (((0 0, 0 5, 5 5, 5 0, 0 0)), ((6 1, 6 2, 7 2, 7 1, 6 1)))") }
32
+ let(:empty_geometry_collection) { GeoRuby::SimpleFeatures::GeometryCollection.from_geometries([], 4326) }
33
+
34
+ it "should return an empty geometry collection if multi polygons are the same" do
35
+ g_multi_polygon.difference(g_multi_polygon).should == empty_geometry_collection
36
+ end
37
+
38
+ it "should return an rgeo polygon if there's only one polygon left' " do
39
+ g_multi_polygon2 = geometry("MULTIPOLYGON (((0 0, 0 5, 5 5, 5 0, 0 0)))")
40
+ g_multi_polygon.difference(g_multi_polygon2).should == geometry("POLYGON ((6 1, 6 2, 7 2, 7 1, 6 1))")
41
+ end
42
+
43
+ it "should return a multi polygon if there's more than one polygon left" do
44
+ g_multi_polygon2 = geometry("MULTIPOLYGON (((0.25 0.25, 0.25 0.5, 0.75 0.5, 0.75 0.25, 0.25 0.25)))")
45
+ g_multi_polygon.difference(g_multi_polygon2).should == geometry("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0.25 0.25,0.75 0.25,0.75 0.5,0.25 0.5,0.25 0.25)),((6 1, 6 2, 7 2, 7 1, 6 1)))")
46
+ end
47
+
48
+ it "should return the same polygon if the polygon to substract isn't inside the polygon" do
49
+ g_multi_polygon2 = geometry("MULTIPOLYGON (((0 0, 0 -1, -1 -1, -1 0, 0 0)))")
50
+ g_multi_polygon.difference(g_multi_polygon2).should == geometry("MULTIPOLYGON (((0 0, 0 5, 5 5, 5 0, 0 0)), ((6 1, 6 2, 7 2, 7 1, 6 1)))")
51
+ end
52
+
53
+ it "should return a multi polygon with 2 holes" do
54
+ g_multi_polygon2 = geometry("MULTIPOLYGON ( ((1 1, 2 1, 2 2, 1 2, 1 1)), ((3 3, 4 3, 4 4, 3 4, 3 3)) )")
55
+ g_multi_polygon.difference(g_multi_polygon2).should == geometry("MULTIPOLYGON ( ((0 0, 0 5, 5 5, 5 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1), (3 3, 4 3, 4 4, 3 4, 3 3)), ((6 1, 6 2, 7 2, 7 1, 6 1)) )")
56
+ end
57
+
58
+ end
59
+
60
+ describe "#to_rgeo" do
61
+ let(:g_multi_polygon) { geometry("MULTIPOLYGON(((0.0 0.0,0.0 1.0,1.0 1.0,1.0 0.0,0.0 0.0),(0.25 0.25,0.75 0.25,0.75 0.5,0.25 0.5,0.25 0.25)),((0.0 2.0,0.0 3.0,3.0 3.0,2.0 2.0,0.0 2.0)))") }
62
+ let(:rg_multi_polygon) { rgeometry("MULTIPOLYGON(((0.0 0.0,0.0 1.0,1.0 1.0,1.0 0.0,0.0 0.0),(0.25 0.25,0.75 0.25,0.75 0.5,0.25 0.5,0.25 0.25)),((0.0 2.0,0.0 3.0,3.0 3.0,2.0 2.0,0.0 2.0)))") }
63
+
64
+ it "should return an rgeo multi polygons" do
65
+ g_multi_polygon.to_rgeo.should == rg_multi_polygon
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,248 @@
1
+ require 'spec_helper'
2
+
3
+ describe GeoRuby::SimpleFeatures::Point do
4
+
5
+ subject { point 1.0, 2.0 }
6
+
7
+ describe "#==" do
8
+
9
+ let(:other) { mock :other, :lat => nil, :lng => nil }
10
+
11
+ it "should return false if other is nil" do
12
+ subject.should_not == nil
13
+ end
14
+
15
+ it "should return true if spherical_distance to other is smaller than 10e-3 (< 1m)" do
16
+ subject.stub :spherical_distance => 10e-4
17
+ subject.should == other
18
+ end
19
+
20
+ it "should return false if spherical distance to other is greater or equals to 10e-3 (>= 1m)" do
21
+ subject.stub :spherical_distance => 10e-3
22
+ subject.should_not == other
23
+ end
24
+
25
+ it "should match the same point into 2 different srid" do
26
+ subject.to_google.should == subject
27
+ end
28
+
29
+ end
30
+
31
+ describe "to_rgeo" do
32
+
33
+ it "should have the same information" do
34
+ subject.to_rgeo.should have_same(:x, :y, :srid).than(subject)
35
+ end
36
+
37
+ end
38
+
39
+ describe ".centroid" do
40
+
41
+ def centroid(points)
42
+ points = points(points) if String === points
43
+ GeoRuby::SimpleFeatures::Point.centroid points
44
+ end
45
+
46
+ it "should return nil if no points in input" do
47
+ centroid([]).should be_nil
48
+ end
49
+
50
+ it "should return point in input if only one" do
51
+ centroid("0 0").should == point(0,0)
52
+ end
53
+
54
+ it "should return middle if two points in input" do
55
+ centroid("0 0,1 0").should == point(0.5,0)
56
+ end
57
+
58
+ it "should return centroid of given points" do
59
+ centroid("0 0,0 2,2 2,2 0").should == point(1,1)
60
+ end
61
+
62
+ it "should have the same srid than points" do
63
+ google_point = point.to_google
64
+ centroid([google_point]).srid.should == google_point.srid
65
+ end
66
+
67
+ end
68
+
69
+ describe "#to_proj4" do
70
+
71
+ it "should return a Proj4::Point" do
72
+ subject.to_proj4.should be_instance_of(Proj4::Point)
73
+ end
74
+
75
+ it "should use the given ratio (if specified)" do
76
+ subject.to_proj4(10).x.should == subject.x * 10
77
+ subject.to_proj4(10).y.should == subject.y * 10
78
+ end
79
+
80
+ context "when Point is wgs84" do
81
+
82
+ it "should transform x to radians (using ratio #{Proj4::DEG_TO_RAD})" do
83
+ subject.to_proj4.x.should == subject.x * Proj4::DEG_TO_RAD
84
+ end
85
+
86
+ it "should transform y to radians (using ratio #{Proj4::DEG_TO_RAD})" do
87
+ subject.to_proj4.y.should == subject.y * Proj4::DEG_TO_RAD
88
+ end
89
+
90
+ end
91
+
92
+ it "should have the same z" do
93
+ subject.to_proj4.z.should == nil
94
+ end
95
+
96
+ end
97
+
98
+ describe ".from_pro4j" do
99
+
100
+ let(:proj4_point) { subject.to_proj4 }
101
+ let(:srid) { subject.srid }
102
+
103
+ def from_pro4j(point, srid = srid)
104
+ GeoRuby::SimpleFeatures::Point.from_pro4j point, srid
105
+ end
106
+
107
+ it "should transform x to degres" do
108
+ from_pro4j(proj4_point).x.should == proj4_point.x * Proj4::RAD_TO_DEG
109
+ end
110
+
111
+ it "should transform y to degres" do
112
+ from_pro4j(proj4_point).y.should == proj4_point.y * Proj4::RAD_TO_DEG
113
+ end
114
+
115
+ it "should have the specified srid" do
116
+ from_pro4j(proj4_point, srid).srid.should == srid
117
+ end
118
+
119
+ end
120
+
121
+ it "should be used as Hash key" do
122
+ hash = { point(0,0) => :found }
123
+ hash[point(0,0)].should == :found
124
+ end
125
+
126
+ describe "#eql?" do
127
+
128
+ it "should compare x, y, z and srid" do
129
+ point(0,0).should eq(point(0,0))
130
+ end
131
+
132
+ end
133
+
134
+ describe "hash" do
135
+
136
+ it "should use x, y, z and srid" do
137
+ point(0,0).hash.should == point(0,0).hash
138
+ end
139
+
140
+ end
141
+
142
+ describe "to_s" do
143
+
144
+ it "should contain 'y,x'" do
145
+ point(1,2).to_s.should == "2,1"
146
+ end
147
+
148
+ end
149
+
150
+ describe "#bounding_box" do
151
+
152
+ it "should be itself twice" do
153
+ subject.bounding_box.should == [subject, subject]
154
+ end
155
+
156
+ it "should return 3 points with_z" do
157
+ subject.with_z = true
158
+ subject.bounding_box.should == [subject] * 3
159
+ end
160
+
161
+ end
162
+
163
+ describe "#projection" do
164
+
165
+ let(:projection) { mock :projection }
166
+
167
+ it "should return projection associated to srid" do
168
+ Proj4::Projection.should_receive(:for_srid).with(subject.srid).and_return(projection)
169
+ subject.projection.should == projection
170
+ end
171
+
172
+ end
173
+
174
+ describe "#project_to" do
175
+
176
+ let(:tour_eiffel_in_wgs84) { point 2.2946, 48.8580, 4326 }
177
+ let(:tour_eiffel_in_google) { point 255433.703574246, 6250801.22232508, 900913 }
178
+
179
+ it "should return the Point when the target srid is the same" do
180
+ subject.project_to(subject.srid).should == subject
181
+ end
182
+
183
+ it "should return a Point with the target srid" do
184
+ subject.project_to(900913).srid.should == 900913
185
+ end
186
+
187
+ it "should return a Point projected into the target srid" do
188
+ tour_eiffel_in_google.project_to(tour_eiffel_in_wgs84.srid).should be_close_to tour_eiffel_in_wgs84
189
+ tour_eiffel_in_wgs84.project_to(tour_eiffel_in_google.srid).should be_close_to tour_eiffel_in_google
190
+ end
191
+
192
+ end
193
+
194
+ describe ".bounds" do
195
+
196
+ let(:some_points) { points("0 0,1 1,1 0,0 1") }
197
+
198
+ it "should return an Envelope with the same srid than points" do
199
+ GeoRuby::SimpleFeatures::Point.bounds(some_points).srid.should == GeoRuby::SimpleFeatures::Point.srid!(some_points)
200
+ end
201
+
202
+ it "should return '0 0,1 1' for '0 0,1 1,1 0,0 1'" do
203
+ bounds = GeoRuby::SimpleFeatures::Point.bounds(points('0 0,1 1,1 0,0 1'))
204
+ bounds.lower_corner.should == point(0,0)
205
+ bounds.upper_corner.should == point(1,1)
206
+ end
207
+
208
+ end
209
+
210
+ describe "#endpoint" do
211
+
212
+ let(:distance) { 10000 }
213
+
214
+ it "should return a point at the given distance" do
215
+ subject.endpoint(rand(360), distance).spherical_distance(subject).should be_within(0.001).of(distance)
216
+ end
217
+
218
+ it "should not change longitude when heading is 0 (north)" do
219
+ subject.endpoint(0, distance).should have_same(:lng).than(subject)
220
+ end
221
+
222
+ it "should not change latitude when heading is 90 (east)" do
223
+ subject.endpoint(90, distance).lat.should be_within(0.0001).of(subject.lat)
224
+ end
225
+
226
+ end
227
+
228
+ describe "#change" do
229
+
230
+ it "should change x if specified" do
231
+ subject.change(:x => 42).x.should == 42
232
+ end
233
+
234
+ it "should change y if specified" do
235
+ subject.change(:y => 42).y.should == 42
236
+ end
237
+
238
+ it "should change the srid if specified" do
239
+ subject.change(:srid => 1).srid.should == 1
240
+ end
241
+
242
+ it "should not change unspecified attributes" do
243
+ subject.change(:x => 1).should have_same(:y, :srid, :with_z, :with_m).than(subject)
244
+ end
245
+
246
+ end
247
+
248
+ end
@@ -0,0 +1,175 @@
1
+ require 'spec_helper'
2
+
3
+ describe GeoRuby::SimpleFeatures::Polygon do
4
+
5
+ describe "circle" do
6
+
7
+ let(:center) { point 1,1 }
8
+ let(:radius) { 1000 }
9
+ let(:sides) { 8 }
10
+
11
+ def circle(arguments = {})
12
+ arguments = { :center => center, :radius => radius, :sides => sides }.merge(arguments)
13
+ GeoRuby::SimpleFeatures::Polygon.circle *arguments.values_at(:center, :radius, :sides)
14
+ end
15
+
16
+ it "should create a square" do
17
+ p1 = center.endpoint 0, radius
18
+ p2 = center.endpoint 90, radius
19
+ p3 = center.endpoint 180, radius
20
+ p4 = center.endpoint 270, radius
21
+
22
+ circle(:sides => 4).should == polygon(p1, p2, p3, p4, p1)
23
+ end
24
+
25
+ it "should have the given side count" do
26
+ circle(:sides => 16).side_count.should == 16
27
+ end
28
+
29
+ it "should be closed" do
30
+ circle(:sides => 16).rings.each do |ring|
31
+ ring.is_closed.should be_true
32
+ end
33
+ end
34
+
35
+ it "should have all its points as the radius distance of the center" do
36
+ circle.points.all? do |point|
37
+ point.spherical_distance(center).should be_within(0.0001).of(radius)
38
+ end
39
+ end
40
+
41
+ it "should have the same distance between all its points" do
42
+ average_distance = circle.perimeter / circle.side_count
43
+ circle.points.each_cons(2) do |point, next_point|
44
+ point.spherical_distance(next_point).should be_within(0.01).of(average_distance)
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#project_to" do
50
+
51
+ let(:target_srid) { 900913 }
52
+ subject { polygon("(0 0,1 1,1 0)") }
53
+
54
+ it "should project all rings into wgs84" do
55
+ subject.project_to(target_srid).rings.each_with_index do |ring, index|
56
+ ring.should == subject[index].project_to(target_srid)
57
+ end
58
+ end
59
+
60
+ it "should have the target srid" do
61
+ subject.project_to(target_srid).srid.should == target_srid
62
+ end
63
+
64
+ it "should not change other attributes" do
65
+ subject.project_to(target_srid).should have_same(:with_z, :with_m).than(subject)
66
+ end
67
+
68
+ end
69
+
70
+ describe "to_rgeo" do
71
+
72
+ it "should return a rgeo polygon" do
73
+ rgeo_polygon = rgeometry("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))")
74
+ geo_polygon = geometry("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))")
75
+ geo_polygon.to_rgeo.should == rgeo_polygon
76
+ end
77
+
78
+ it "should return a rgeo polygon with an hole" do
79
+ rgeo_polygon = rgeometry("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))")
80
+ geo_polygon = geometry("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1) )")
81
+ geo_polygon.to_rgeo.should == rgeo_polygon
82
+ end
83
+
84
+ end
85
+
86
+ describe "centroid" do
87
+ let(:georuby_polygon){ geometry("POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))") }
88
+
89
+ it "should return centroid for a polygon" do
90
+ georuby_polygon.centroid.should == point(1,1)
91
+ end
92
+
93
+ end
94
+
95
+
96
+ describe "union" do
97
+
98
+ let(:georuby_polygon) { geometry("POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))") }
99
+
100
+ it "should return the same polygon than in input" do
101
+ GeoRuby::SimpleFeatures::Polygon.union([georuby_polygon, georuby_polygon]).should == georuby_polygon
102
+ end
103
+
104
+ it "should return union of 2 polygons which have a common side" do
105
+ result = geometry("POLYGON((0.0 0.0,0.0 2.0,0.0 4.0,2.0 4.0,2.0 2.0,2.0 0.0,0.0 0.0))")
106
+ georuby_polygon2 = geometry("POLYGON((0 2, 0 4, 2 4, 2 2, 0 2))")
107
+ GeoRuby::SimpleFeatures::Polygon.union([georuby_polygon, georuby_polygon2]).should == result
108
+ end
109
+
110
+ it "should return 2 polygons which have an area in common" do
111
+ result = geometry("POLYGON((0 0,0 1,0 2,0 4,2 4,2 2,2 1,2 0,0 0))")
112
+ georuby_polygon2 = geometry("POLYGON((0 1, 0 4, 2 4, 2 1, 0 1))")
113
+ GeoRuby::SimpleFeatures::Polygon.union([georuby_polygon, georuby_polygon2]).should == result
114
+ end
115
+
116
+ it "should return 2 polygons which have no intersection" do
117
+ result = geometry("MULTIPOLYGON( ((0 0, 0 2, 2 2, 2 0, 0 0)), ((3 3, 3 4, 4 4, 4 3, 3 3)) )")
118
+ georuby_polygon2 = geometry("POLYGON((3 3, 4 3, 4 4, 3 4, 3 3))")
119
+ GeoRuby::SimpleFeatures::Polygon.union([georuby_polygon, georuby_polygon2]).should == result
120
+ end
121
+
122
+ end
123
+
124
+ describe "intersect" do
125
+ let(:georuby_polygon){ polygon("(0 0,0 2,2 2,2 0,0 0)") }
126
+ let(:georuby_polygon2){ polygon("(0 0,0 4,2 4,2 0,0 0)") }
127
+
128
+ it "should return intersect of polygons" do
129
+ test = GeoRuby::SimpleFeatures::Polygon.intersection([georuby_polygon, georuby_polygon2])
130
+ GeoRuby::SimpleFeatures::Polygon.intersection([georuby_polygon, georuby_polygon2]).text_representation.should == georuby_polygon.text_representation
131
+ end
132
+ end
133
+
134
+ describe "#difference" do
135
+ let(:georuby_polygon) { polygon("(0 0,0 2,2 2,2 0,0 0)") }
136
+ let(:georuby_polygon2){ polygon("(0 0,0 1,2 1,2 0,0 0)") }
137
+
138
+ it "should be empty geometry collection if polygons are the same" do
139
+ georuby_polygon.difference(georuby_polygon).should == GeoRuby::SimpleFeatures::GeometryCollection.from_geometries([], 4326)
140
+ end
141
+
142
+ it "should return polygon('(0 1,0 2,2 2,2 1,0 1)' as result" do
143
+ result = polygon("(0 1,0 2,2 2,2 1,0 1)")
144
+ georuby_polygon.difference(georuby_polygon2).should == result
145
+ end
146
+
147
+ it "should be empty geometry collection if polygon is smaller than the other" do
148
+ georuby_polygon2.difference(georuby_polygon).should == GeoRuby::SimpleFeatures::GeometryCollection.from_geometries([], 4326)
149
+ end
150
+
151
+ it "should return a result if we make difference with a multi polygon" do
152
+ geo_polygon = geometry("POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))")
153
+ geo_multi_polygon = geometry("MULTIPOLYGON ( ((1 1, 2 1, 2 2, 1 2, 1 1)), ((3 3, 4 3, 4 4, 3 4, 3 3)) )")
154
+ geo_polygon.difference(geo_multi_polygon).should == geometry("POLYGON ( ((0 0, 0 5, 5 5, 5 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1), (3 3, 4 3, 4 4, 3 4, 3 3)) )")
155
+ end
156
+
157
+ end
158
+
159
+ describe "#==" do
160
+
161
+ it "should be true when points are same" do
162
+ geometry("POLYGON((0 0,0 1,2 1,2 0,0 0))").should == geometry("POLYGON((0 0,0 1,2 1,2 0,0 0))")
163
+ end
164
+
165
+ end
166
+
167
+ describe "side_count" do
168
+
169
+ it "should return 3 for a triangle" do
170
+ polygon("(0 0,1 0,0 1,0 0)").side_count.should == 3
171
+ end
172
+
173
+ end
174
+
175
+ end