geos-extensions 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+
2
+ module Geos::Helper
3
+ JS_ESCAPE_MAP = {
4
+ '\\' => '\\\\',
5
+ '</' => '<\/',
6
+ "\r\n" => '\n',
7
+ "\n" => '\n',
8
+ "\r" => '\n',
9
+ '"' => '\\"',
10
+ "'" => "\\'"
11
+ }
12
+
13
+ # Escape carrier returns and single and double quotes for JavaScript
14
+ # segments. Borrowed from ActiveSupport.
15
+ def self.escape_javascript(javascript) #:nodoc:
16
+ if javascript
17
+ javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { JS_ESCAPE_MAP[$1] }
18
+ else
19
+ ''
20
+ end
21
+ end
22
+
23
+ def self.camelize(lower_case_and_underscored_word, first_letter_in_uppercase = false)
24
+ if first_letter_in_uppercase
25
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
26
+ else
27
+ lower_case_and_underscored_word.to_s[0..0].downcase + camelize(lower_case_and_underscored_word, true)[1..-1]
28
+ end
29
+ end
30
+
31
+ def self.xml_options(*args) #:nodoc:
32
+ xml = if Builder::XmlMarkup === args.first
33
+ args.first
34
+ else
35
+ Builder::XmlMarkup.new(:indent => 4)
36
+ end
37
+
38
+ options = if Hash === args.last
39
+ args.last
40
+ else
41
+ Hash.new
42
+ end
43
+
44
+ [ xml, options ]
45
+ end
46
+
47
+ def self.number_with_precision(number, precision = 6)
48
+ rounded_number = (Float(number) * (10 ** precision)).round.to_f / 10 ** precision
49
+ "%01.#{precision}f" % rounded_number
50
+ end
51
+ end
@@ -0,0 +1,7 @@
1
+
2
+ module Geos
3
+ module GoogleMaps
4
+ autoload :PolylineEncoder, File.join(GEOS_EXTENSIONS_BASE, *%w{ google_maps polyline_encoder })
5
+ end
6
+ end
7
+
@@ -0,0 +1,60 @@
1
+
2
+ module Geos
3
+ module GoogleMaps
4
+ module PolylineEncoder
5
+
6
+ class << self
7
+ # Encodes a series of points into Google's encoded polyline format. See
8
+ # http://code.google.com/apis/maps/documentation/reference.html for
9
+ # details, specifically GPolyline#fromEncoded and
10
+ # GPolygon#fromEncoded.
11
+ #
12
+ # The level parameter is the zoom level you're encoding at. See the
13
+ # Google Maps API reference for details on that.
14
+ def encode(points, level = 3)
15
+ encoded_points = String.new
16
+ encoded_levels = String.new
17
+
18
+ prev_lat = 0
19
+ prev_lng = 0
20
+
21
+ points.each do |p|
22
+ lat_e5 = (p[1] * 1e5).floor
23
+ lng_e5 = (p[0] * 1e5).floor
24
+
25
+ cur_lat = lat_e5 - prev_lat
26
+ cur_lng = lng_e5 - prev_lng
27
+
28
+ prev_lat = lat_e5
29
+ prev_lng = lng_e5
30
+
31
+ encoded_points += encode_signed_number(cur_lat) + encode_signed_number(cur_lng)
32
+ encoded_levels += encode_number(level)
33
+ end
34
+
35
+ { :points => encoded_points, :levels => encoded_levels }
36
+ end
37
+
38
+ protected
39
+
40
+ # Encodes a signed number into the Google Maps encoded polyline format.
41
+ def encode_signed_number(n) #:nodoc:
42
+ signed = n << 1
43
+ signed = ~(signed) if n < 0
44
+ encode_number signed
45
+ end
46
+
47
+ # Encodes a number into the Google Maps encoded polyline format.
48
+ def encode_number(n) #:nodoc:
49
+ str = String.new
50
+ while (n >= 0x20) do
51
+ str += ((0x20 | (n & 0x1f)) + 63).chr
52
+ n >>= 5
53
+ end
54
+ str + (n + 63).chr
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,112 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class GeosReaderTests < Test::Unit::TestCase
6
+ include TestHelper
7
+
8
+ def test_from_wkb_bin
9
+ point = Geos.from_wkb_bin(POINT_WKB_BIN)
10
+ polygon = Geos.from_wkb_bin(POLYGON_WKB_BIN)
11
+
12
+ assert_saneness_of_point(point)
13
+ assert_saneness_of_polygon(polygon)
14
+ end
15
+
16
+ def test_from_wkb
17
+ point = Geos.from_wkb(POINT_WKB)
18
+ polygon = Geos.from_wkb(POLYGON_WKB)
19
+
20
+ assert_saneness_of_point(point)
21
+ assert_saneness_of_polygon(polygon)
22
+ end
23
+
24
+ def test_from_wkt
25
+ point = Geos.from_wkt(POINT_WKT)
26
+ polygon = Geos.from_wkt(POLYGON_WKT)
27
+
28
+ assert_saneness_of_point(point)
29
+ assert_saneness_of_polygon(polygon)
30
+ end
31
+
32
+ def test_from_ewkb_bin
33
+ point = Geos.from_wkb_bin(POINT_EWKB_BIN)
34
+ polygon = Geos.from_wkb_bin(POLYGON_EWKB_BIN)
35
+
36
+ assert_saneness_of_point(point)
37
+ assert_equal(4326, point.srid)
38
+
39
+ assert_saneness_of_polygon(polygon)
40
+ assert_equal(4326, polygon.srid)
41
+ end
42
+
43
+ def test_from_ewkb
44
+ point = Geos.from_wkb(POINT_EWKB)
45
+ polygon = Geos.from_wkb(POLYGON_EWKB)
46
+
47
+ assert_saneness_of_point(point)
48
+ assert_equal(4326, point.srid)
49
+
50
+ assert_saneness_of_polygon(polygon)
51
+ assert_equal(4326, polygon.srid)
52
+ end
53
+
54
+ def test_from_ewkt
55
+ point = Geos.from_wkt(POINT_EWKT)
56
+ polygon = Geos.from_wkt(POLYGON_EWKT)
57
+
58
+ assert_saneness_of_point(point)
59
+ assert_equal(4326, point.srid)
60
+
61
+ assert_saneness_of_polygon(polygon)
62
+ assert_equal(4326, polygon.srid)
63
+ end
64
+
65
+ def test_from_g_lat_lng
66
+ point = Geos.from_g_lat_lng(POINT_G_LAT_LNG)
67
+ assert_saneness_of_point(point)
68
+
69
+ point = Geos.from_g_lat_lng(POINT_G_LAT_LNG, :points => true)
70
+ assert_kind_of(Geos::Point, point)
71
+ assert_equal(10, point.lat)
72
+ assert_equal(10.01, point.lng)
73
+ end
74
+
75
+ def test_from_g_lat_lng_bounds
76
+ bounds = Geos.from_g_lat_lng(BOUNDS_G_LAT_LNG)
77
+
78
+ assert_kind_of(Geos::Polygon, bounds)
79
+ assert_equal([ 0, 0 ], bounds.sw.to_a)
80
+ assert_equal([ 5, 5 ], bounds.ne.to_a)
81
+ assert_equal([ 0, 5 ], bounds.nw.to_a)
82
+ assert_equal([ 5, 0 ], bounds.se.to_a)
83
+ end
84
+
85
+ def test_read
86
+ [
87
+ POINT_WKT,
88
+ POINT_EWKT,
89
+ POINT_WKB,
90
+ POINT_WKB_BIN,
91
+ POINT_EWKB,
92
+ POINT_EWKB_BIN,
93
+ POINT_G_LAT_LNG,
94
+ POINT_G_LAT_LNG_URL_VALUE
95
+ ].each do |geom|
96
+ point = Geos.read(geom)
97
+ assert_saneness_of_point(point)
98
+ end
99
+
100
+ [
101
+ POLYGON_WKT,
102
+ POLYGON_EWKT,
103
+ POLYGON_WKB,
104
+ POLYGON_WKB_BIN,
105
+ POLYGON_EWKB,
106
+ POLYGON_EWKB_BIN
107
+ ].each do |geom|
108
+ polygon = Geos.read(geom)
109
+ assert_saneness_of_polygon(polygon)
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,71 @@
1
+
2
+ require 'rubygems'
3
+ require 'test/unit'
4
+ require File.join(File.dirname(__FILE__), %w{ .. lib geos_extensions })
5
+
6
+ puts "Ruby version #{RUBY_VERSION} - #{RbConfig::CONFIG['RUBY_INSTALL_NAME']}"
7
+ puts "GEOS version #{Geos::GEOS_VERSION}"
8
+ if defined?(Geos::FFIGeos)
9
+ puts "Using #{Geos::FFIGeos.geos_library_paths.join(', ')}"
10
+ end
11
+
12
+ module TestHelper
13
+ POINT_WKT = 'POINT(10 10.01)'
14
+ POINT_EWKT = 'SRID=4326; POINT(10 10.01)'
15
+ POINT_WKB = "0101000000000000000000244085EB51B81E052440"
16
+ POINT_WKB_BIN = "\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40"
17
+ POINT_EWKB = "0101000020E6100000000000000000244085EB51B81E052440"
18
+ POINT_EWKB_BIN = "\x01\x01\x00\x00\x20\xE6\x10\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40"
19
+ POINT_G_LAT_LNG = "(10.01, 10)"
20
+ POINT_G_LAT_LNG_URL_VALUE = "10.01,10"
21
+
22
+ POLYGON_WKT = 'POLYGON((0 0, 1 1, 2.5 2.5, 5 5, 0 0))'
23
+ POLYGON_EWKT = 'SRID=4326; POLYGON((0 0, 1 1, 2.5 2.5, 5 5, 0 0))'
24
+ POLYGON_WKB = "
25
+ 0103000000010000000500000000000000000000000000000000000000000000000000F
26
+ 03F000000000000F03F0000000000000440000000000000044000000000000014400000
27
+ 00000000144000000000000000000000000000000000
28
+ ".gsub(/\s/, '')
29
+ POLYGON_WKB_BIN = [
30
+ "\x01\x03\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00",
31
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF0\x3F\x00",
32
+ "\x00\x00\x00\x00\x00\xF0\x3F\x00\x00\x00\x00\x00\x00\x04\x40\x00\x00\x00\x00",
33
+ "\x00\x00\x04\x40\x00\x00\x00\x00\x00\x00\x14\x40\x00\x00\x00\x00\x00\x00\x14",
34
+ "\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
35
+ ].join
36
+ POLYGON_EWKB = "
37
+ 0103000020E610000001000000050000000000000000000000000000000000000000000
38
+ 0000000F03F000000000000F03F00000000000004400000000000000440000000000000
39
+ 1440000000000000144000000000000000000000000000000000
40
+ ".gsub(/\s/, '')
41
+ POLYGON_EWKB_BIN = [
42
+ "\x01\x03\x00\x00\x20\xE6\x10\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00",
43
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
44
+ "\x00\x00\x00\x00\x00\xF0\x3F\x00\x00\x00\x00\x00\x00\xF0\x3F\x00\x00",
45
+ "\x00\x00\x00\x00\x04\x40\x00\x00\x00\x00\x00\x00\x04\x40\x00\x00\x00",
46
+ "\x00\x00\x00\x14\x40\x00\x00\x00\x00\x00\x00\x14\x40\x00\x00\x00\x00",
47
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
48
+ ].join
49
+
50
+ POLYGON_WITH_INTERIOR_RING = "POLYGON((0 0, 5 0, 5 5, 0 5, 0 0),(4 4, 4 1, 1 1, 1 4, 4 4))"
51
+
52
+ BOUNDS_G_LAT_LNG = "((0, 0), (5, 5))"
53
+
54
+ def assert_saneness_of_point(point)
55
+ assert_kind_of(Geos::Point, point)
56
+ assert_equal(10.01, point.lat)
57
+ assert_equal(10, point.lng)
58
+ end
59
+
60
+ def assert_saneness_of_polygon(polygon)
61
+ assert_kind_of(Geos::Polygon, polygon)
62
+ cs = polygon.exterior_ring.coord_seq
63
+ assert_equal([
64
+ [ 0, 0 ],
65
+ [ 1, 1 ],
66
+ [ 2.5, 2.5 ],
67
+ [ 5, 5 ],
68
+ [ 0, 0 ]
69
+ ], cs.to_a)
70
+ end
71
+ end
@@ -0,0 +1,287 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ begin
6
+ require 'json'
7
+ rescue LoadError
8
+ # do nothing
9
+ end
10
+
11
+ begin
12
+ require 'builder'
13
+ require 'stringio'
14
+ rescue LoadError
15
+ # do nothing
16
+ end
17
+
18
+ class GeosWriterTests < Test::Unit::TestCase
19
+ include TestHelper
20
+
21
+ def initialize(*args)
22
+ @point = Geos.read(POINT_EWKB)
23
+ @polygon = Geos.read(POLYGON_EWKB)
24
+ super(*args)
25
+ end
26
+
27
+ def test_to_wkb_bin
28
+ assert_equal(POINT_WKB_BIN, @point.to_wkb_bin)
29
+ assert_equal(POLYGON_WKB_BIN, @polygon.to_wkb_bin)
30
+ end
31
+
32
+ def test_to_wkb
33
+ assert_equal(POINT_WKB, @point.to_wkb)
34
+ assert_equal(POLYGON_WKB, @polygon.to_wkb)
35
+ end
36
+
37
+ def test_to_wkt
38
+ if @point.to_wkt =~ /^POINT\s*\((\d+\.\d+)\s*(\d+\.\d+)\)$/
39
+ lng, lat = $1.to_f, $2.to_f
40
+ end
41
+
42
+ assert_in_delta(lng, 10.00, 0.000001)
43
+ assert_in_delta(lat, 10.01, 0.000001)
44
+ end
45
+
46
+ def test_to_ewkb_bin
47
+ assert_equal(POINT_EWKB_BIN, @point.to_ewkb_bin)
48
+ assert_equal(POLYGON_EWKB_BIN, @polygon.to_ewkb_bin)
49
+ end
50
+
51
+ def test_to_ewkb
52
+ assert_equal(POINT_EWKB, @point.to_ewkb)
53
+ assert_equal(POLYGON_EWKB, @polygon.to_ewkb)
54
+ end
55
+
56
+ def test_to_ewkt
57
+ if @point.to_ewkt =~ /^SRID=4326;\s*POINT\s*\((\d+\.\d+)\s*(\d+\.\d+)\)$/
58
+ lng, lat = $1.to_f, $2.to_f
59
+ end
60
+
61
+ assert_in_delta(lng, 10.00, 0.000001)
62
+ assert_in_delta(lat, 10.01, 0.000001)
63
+ end
64
+
65
+ def test_to_g_lat_lng
66
+ assert_equal("new google.maps.LatLng(10.01, 10.0)", @point.to_g_lat_lng)
67
+ assert_equal("new GLatLng(10.01, 10.0)", @point.to_g_lat_lng(:short_class => true))
68
+ end
69
+
70
+ def test_to_flickr_bbox
71
+ assert_equal('0.0,0.0,5.0,5.0', @polygon.to_flickr_bbox)
72
+ end
73
+
74
+ def test_to_jsonable
75
+ assert_equal({
76
+ :type => "point",
77
+ :lat => 10.01,
78
+ :lng => 10.0
79
+ }, @point.to_jsonable)
80
+
81
+ assert_equal({
82
+ :type => "polygon",
83
+ :polylines => [{
84
+ :points => "??_ibE_ibE_~cH_~cH_hgN_hgN~po]~po]",
85
+ :bounds => {
86
+ :sw => [ 0.0, 0.0 ],
87
+ :ne => [ 5.0, 5.0 ]
88
+ },
89
+ :levels=>"BBBBB"
90
+ }],
91
+ :options => {},
92
+ :encoded => true
93
+ }, @polygon.to_jsonable)
94
+ end
95
+
96
+ if defined?(JSON)
97
+ def test_to_g_polygon
98
+ assert_equal(
99
+ "new google.maps.Polygon([new google.maps.LatLng(0.0, 0.0), new google.maps.LatLng(1.0, 1.0), new google.maps.LatLng(2.5, 2.5), new google.maps.LatLng(5.0, 5.0), new google.maps.LatLng(0.0, 0.0)], null, null, null, null, null, null)",
100
+ @polygon.to_g_polygon
101
+ )
102
+
103
+ assert_equal(
104
+ "new GPolygon([new GLatLng(0.0, 0.0), new GLatLng(1.0, 1.0), new GLatLng(2.5, 2.5), new GLatLng(5.0, 5.0), new GLatLng(0.0, 0.0)], null, null, null, null, null, null)",
105
+ @polygon.to_g_polygon({}, :short_class => true)
106
+ )
107
+
108
+ assert_equal(
109
+ "new google.maps.Polygon([new google.maps.LatLng(0.0, 0.0), new google.maps.LatLng(1.0, 1.0), new google.maps.LatLng(2.5, 2.5), new google.maps.LatLng(5.0, 5.0), new google.maps.LatLng(0.0, 0.0)], '#b00b1e', 5, 0.5, '#b00b1e', null, {\"mouseOutTolerence\":5})",
110
+ @polygon.to_g_polygon(
111
+ :stroke_color => '#b00b1e',
112
+ :stroke_weight => 5,
113
+ :stroke_opacity => 0.5,
114
+ :fill_color => '#b00b1e',
115
+ :polygon_options => {
116
+ :mouse_out_tolerence => 5
117
+ }
118
+ )
119
+ )
120
+ end
121
+
122
+ def test_to_g_polyline
123
+ assert_equal(
124
+ "new google.maps.Polyline([new google.maps.LatLng(0.0, 0.0), new google.maps.LatLng(1.0, 1.0), new google.maps.LatLng(2.5, 2.5), new google.maps.LatLng(5.0, 5.0), new google.maps.LatLng(0.0, 0.0)], null, null, null, null)",
125
+ @polygon.to_g_polyline
126
+ )
127
+
128
+ assert_equal(
129
+ "new GPolyline([new GLatLng(0.0, 0.0), new GLatLng(1.0, 1.0), new GLatLng(2.5, 2.5), new GLatLng(5.0, 5.0), new GLatLng(0.0, 0.0)], null, null, null, null)",
130
+ @polygon.to_g_polyline({}, :short_class => true)
131
+ )
132
+
133
+ assert_equal(
134
+ "new google.maps.Polyline([new google.maps.LatLng(0.0, 0.0), new google.maps.LatLng(1.0, 1.0), new google.maps.LatLng(2.5, 2.5), new google.maps.LatLng(5.0, 5.0), new google.maps.LatLng(0.0, 0.0)], '#b00b1e', 5, 0.5, {\"mouseOutTolerence\":5})",
135
+ @polygon.to_g_polyline(
136
+ :color => '#b00b1e',
137
+ :weight => 5,
138
+ :opacity => 0.5,
139
+ :polyline_options => {
140
+ :mouse_out_tolerence => 5
141
+ }
142
+ )
143
+ )
144
+ end
145
+
146
+ def test_to_g_marker_long
147
+ marker = @point.to_g_marker
148
+
149
+ lat, lng, json = if marker =~ /^new\s+
150
+ google\.maps\.Marker\(
151
+ new\s+google\.maps\.LatLng\(
152
+ (\d+\.\d+)\s*,\s*
153
+ (\d+\.\d+)
154
+ \),\s*
155
+ ((\{\}))
156
+ \)
157
+ /x
158
+ [ $1, $2, $3 ]
159
+ end
160
+
161
+ assert_in_delta(lng.to_f, 10.00, 0.000001)
162
+ assert_in_delta(lat.to_f, 10.01, 0.000001)
163
+ assert_equal(
164
+ {},
165
+ JSON.load(json)
166
+ )
167
+ end
168
+
169
+ def test_to_g_marker_short_class
170
+ marker = @point.to_g_marker({}, :short_class => true)
171
+
172
+ lat, lng, json = if marker =~ /^new\s+
173
+ GMarker\(
174
+ new\s+GLatLng\(
175
+ (\d+\.\d+)\s*,\s*
176
+ (\d+\.\d+)
177
+ \),\s*
178
+ (\{\})
179
+ \)
180
+ /x
181
+ [ $1, $2, $3 ]
182
+ end
183
+
184
+ assert_in_delta(lng.to_f, 10.00, 0.000001)
185
+ assert_in_delta(lat.to_f, 10.01, 0.000001)
186
+ assert_equal(
187
+ {},
188
+ JSON.load(json)
189
+ )
190
+ end
191
+
192
+
193
+ def test_to_g_marker_with_options
194
+ marker = @point.to_g_marker(
195
+ :bounce_gravity => 1,
196
+ :bouncy => true
197
+ )
198
+
199
+ lat, lng, json = if marker =~ /^new\s+
200
+ google\.maps\.Marker\(
201
+ new\s+google\.maps\.LatLng\(
202
+ (\d+\.\d+)\s*,\s*
203
+ (\d+\.\d+)
204
+ \),\s*
205
+ (\{[^}]+\})
206
+ \)
207
+ /x
208
+ [ $1, $2, $3 ]
209
+ end
210
+
211
+ assert_in_delta(lng.to_f, 10.00, 0.000001)
212
+ assert_in_delta(lat.to_f, 10.01, 0.000001)
213
+ assert_equal(
214
+ { "bounceGravity" => 1, "bouncy" => true },
215
+ JSON.load(json)
216
+ )
217
+ end
218
+
219
+ def test_to_g_json_point
220
+ assert_equal(
221
+ { :coordinates => [ 10.0, 10.01, 0 ] },
222
+ @point.to_g_json_point
223
+ )
224
+ end
225
+
226
+ def test_to_g_lat_lon_box
227
+ assert_equal(
228
+ { :east => 5.0, :west => 0.0, :north => 5.0, :south => 0.0},
229
+ @polygon.to_g_lat_lon_box
230
+ )
231
+ end
232
+ end
233
+
234
+ if defined?(Builder::XmlMarkup)
235
+ def test_to_kml_point
236
+ out = StringIO.new
237
+ xml = Builder::XmlMarkup.new(:target => out)
238
+ @point.to_kml(xml, {
239
+ :extrude => true,
240
+ :altitude_mode => :relative_to_ground
241
+ })
242
+ out.rewind
243
+
244
+ assert_equal("<Point id=\"\"><extrude>true</extrude><altitudeMode>relativeToGround</altitudeMode><coordinates>10.0,10.01</coordinates></Point>", out.read)
245
+ end
246
+
247
+ def test_to_kml_polygon
248
+ out = StringIO.new
249
+ xml = Builder::XmlMarkup.new(:target => out)
250
+ @polygon.to_kml(xml, {
251
+ :extrude => true,
252
+ :altitude_mode => :relative_to_ground
253
+ })
254
+ out.rewind
255
+
256
+ assert_equal("<Polygon id=\"\"><extrude>true</extrude><altitudeMode>relativeToGround</altitudeMode><outerBoundaryIs><LinearRing><coordinates>0.0,0.0 1.0,1.0 2.5,2.5 5.0,5.0 0.0,0.0</coordinates></LinearRing></outerBoundaryIs></Polygon>",
257
+ out.read
258
+ )
259
+ end
260
+
261
+ def test_to_kml_polygon_with_interior_ring
262
+ out = StringIO.new
263
+ polygon = Geos.read(POLYGON_WITH_INTERIOR_RING)
264
+ xml = Builder::XmlMarkup.new(:target => out)
265
+ polygon.to_kml(xml, :interior_rings => true)
266
+ out.rewind
267
+
268
+ assert_equal(
269
+ "<Polygon id=\"\"><outerBoundaryIs><LinearRing><coordinates>0.0,0.0 5.0,0.0 5.0,5.0 0.0,5.0 0.0,0.0</coordinates></LinearRing></outerBoundaryIs><innerBoundaryIs><LinearRing><coordinates>4.0,4.0 4.0,1.0 1.0,1.0 1.0,4.0 4.0,4.0</coordinates></LinearRing></innerBoundaryIs></Polygon>",
270
+ out.read
271
+ )
272
+ end
273
+
274
+ def test_to_georss
275
+ out = StringIO.new
276
+ polygon = Geos.read(POLYGON_WITH_INTERIOR_RING)
277
+ xml = Builder::XmlMarkup.new(:target => out)
278
+ polygon.to_georss(xml)
279
+ out.rewind
280
+
281
+ assert_equal(
282
+ "<georss:where><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>0.0 0.0 0.0 5.0 5.0 5.0 5.0 0.0 0.0 0.0</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></georss:where>",
283
+ out.read
284
+ )
285
+ end
286
+ end
287
+ end