georuby-ext 0.0.1 → 0.0.2

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