ruby_kml 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +7 -0
- data/README.md +34 -0
- data/Rakefile +52 -0
- data/examples/melbourne-stations.kml +18 -0
- data/lib/kml/color_style.rb +34 -0
- data/lib/kml/container.rb +42 -0
- data/lib/kml/document.rb +46 -0
- data/lib/kml/feature.rb +185 -0
- data/lib/kml/folder.rb +29 -0
- data/lib/kml/geometry.rb +102 -0
- data/lib/kml/ground_overlay.rb +18 -0
- data/lib/kml/hot_spot.rb +31 -0
- data/lib/kml/icon.rb +15 -0
- data/lib/kml/icon_style.rb +52 -0
- data/lib/kml/lat_lon_box.rb +36 -0
- data/lib/kml/line_string.rb +40 -0
- data/lib/kml/line_style.rb +15 -0
- data/lib/kml/linear_ring.rb +67 -0
- data/lib/kml/link.rb +51 -0
- data/lib/kml/look_at.rb +28 -0
- data/lib/kml/model.rb +40 -0
- data/lib/kml/multi_geometry.rb +26 -0
- data/lib/kml/object.rb +37 -0
- data/lib/kml/overlay.rb +21 -0
- data/lib/kml/placemark.rb +60 -0
- data/lib/kml/point.rb +65 -0
- data/lib/kml/poly_style.rb +16 -0
- data/lib/kml/polygon.rb +91 -0
- data/lib/kml/screen_overlay.rb +61 -0
- data/lib/kml/snippet.rb +25 -0
- data/lib/kml/style.rb +23 -0
- data/lib/kml/style_map.rb +39 -0
- data/lib/kml/style_selector.rb +7 -0
- data/lib/kml/version.rb +9 -0
- data/lib/kml_file.rb +55 -0
- data/lib/ruby_kml.rb +8 -0
- data/ruby_kml.gemspec +14 -0
- data/test/cdata_and_snippet.kml +21 -0
- data/test/ground_overlays.kml +25 -0
- data/test/kml/point_test.rb +10 -0
- data/test/kml_file_test.rb +255 -0
- data/test/paths.kml +33 -0
- data/test/polygon.kml +20 -0
- data/test/polygon_inner.kml +25 -0
- data/test/polygon_style.kml +24 -0
- data/test/simple_placemark.kml +12 -0
- data/test/style_map.kml +40 -0
- data/test/test_helper.rb +11 -0
- metadata +124 -0
data/lib/kml/style.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module KML
|
2
|
+
# A Style defines an addressable style group that can be referenced by StyleMaps and Features. Styles affect
|
3
|
+
# how Geometry is presented in the 3D viewer and how Features appear in the Places panel of the List view.
|
4
|
+
# Shared styles are collected in a Document and must have an id defined for them so that they can be referenced
|
5
|
+
# by the individual Features that use them.
|
6
|
+
class Style < StyleSelector
|
7
|
+
attr_accessor :icon_style
|
8
|
+
attr_accessor :label_style
|
9
|
+
attr_accessor :line_style
|
10
|
+
attr_accessor :poly_style
|
11
|
+
attr_accessor :balloon_style
|
12
|
+
attr_accessor :list_style
|
13
|
+
|
14
|
+
def render(xm=Builder::XmlMarkup.new(:indent => 2))
|
15
|
+
xm.Style(:id => id) {
|
16
|
+
%w(Icon Label Line Poly Balloon List).each do |name|
|
17
|
+
field = "#{name.downcase}_style".to_sym
|
18
|
+
self.__send__(field).render(xm) unless self.__send__(field).nil?
|
19
|
+
end
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Source file that defines a StyleMap element
|
2
|
+
#
|
3
|
+
# <StyleMap id="ID">
|
4
|
+
# <!-- extends StyleSelector -->
|
5
|
+
# <!-- elements specific to StyleMap -->
|
6
|
+
# <Pair id="ID">
|
7
|
+
# <key>normal</key> <!-- kml:styleStateEnum: normal or highlight
|
8
|
+
# <styleUrl>...</styleUrl> <!-- anyURI -->
|
9
|
+
# </Pair>
|
10
|
+
# </StyeMap>
|
11
|
+
|
12
|
+
module KML #:nodoc:
|
13
|
+
# A StyleMap maps between two different icon styles. Typically a StyleMap element is used to provide
|
14
|
+
# separate normal and highlighted styles for a placemark, so that the highlighted version appears when
|
15
|
+
# the user mouses over the icon in Google Earth.
|
16
|
+
class StyleMap < StyleSelector
|
17
|
+
# Key/styleUrl pairs
|
18
|
+
attr_accessor :pairs
|
19
|
+
|
20
|
+
# Get the pairs Hash. Each key/value pair maps a mode (normal or highlight) to the predefined style URL.
|
21
|
+
# Each pair contains a key and a value which references the style. For referenced style elements that
|
22
|
+
# are local to the KML document, a simple # referencing is used. For styles that are contained in
|
23
|
+
# external files, use a full URL along with # referencing.
|
24
|
+
def pairs
|
25
|
+
@pairs ||= {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def render(xm=Builder::XmlMarkup.new(:indent => 2))
|
29
|
+
xm.StyleMap(:id => id) {
|
30
|
+
pairs.each do |key, value|
|
31
|
+
xm.Pair {
|
32
|
+
xm.key(key)
|
33
|
+
xm.styleUrl(value)
|
34
|
+
}
|
35
|
+
end
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/kml/version.rb
ADDED
data/lib/kml_file.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# The KMLFile class is the top level class for constructing KML files. To create a new KML file
|
2
|
+
# create a KMLFile instance and add KML objects to its objects. For example:
|
3
|
+
#
|
4
|
+
# f = KMLFile.new
|
5
|
+
# f.objects << Placemark.new(
|
6
|
+
# :name => 'Simple placemark',
|
7
|
+
# :description => 'Attached to the ground. Intelligently places itself at the height of the underlying terrain.',
|
8
|
+
# :geometry => Point.new(:coordinates=>'-122.0822035425683,37.42228990140251,0')
|
9
|
+
# )
|
10
|
+
# puts f.render
|
11
|
+
class KMLFile
|
12
|
+
# The objects in the KML file
|
13
|
+
def objects
|
14
|
+
@objects ||= []
|
15
|
+
end
|
16
|
+
alias :features :objects
|
17
|
+
|
18
|
+
# Render the KML file
|
19
|
+
def render(xm=Builder::XmlMarkup.new(:indent => 2))
|
20
|
+
xm.instruct!
|
21
|
+
xm.kml(:xmlns => 'http://earth.google.com/kml/2.1'){
|
22
|
+
objects.each { |o| o.render(xm) }
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def save filename
|
27
|
+
File.open(filename, 'w') { |f| f.write render }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Parse the KML file using nokogiri
|
31
|
+
# <kml xmlns="http://www.opengis.net/kml/2.2">
|
32
|
+
# <NetworkLinkControl> ... </NetworkLinkControl>
|
33
|
+
# <!-- 0 or 1 Feature elements -->
|
34
|
+
# </kml>
|
35
|
+
def self.parse(io)
|
36
|
+
kml = self.new
|
37
|
+
doc = Nokogiri::XML::Document.parse(io)
|
38
|
+
doc.root.element_children.each do |cld|
|
39
|
+
case cld.name
|
40
|
+
when 'Document'
|
41
|
+
kml.features << KML::Document.parse(cld)
|
42
|
+
when 'Folder'
|
43
|
+
when 'NetworkLink'
|
44
|
+
when 'Placemark'
|
45
|
+
when 'GroundOverlay'
|
46
|
+
when 'PhotoOverlay'
|
47
|
+
when 'ScreenOverlay'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
kml
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
require 'kml/object'
|
data/lib/ruby_kml.rb
ADDED
data/ruby_kml.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.version = "0.1.7"
|
3
|
+
s.date = "2012-05-07"
|
4
|
+
s.name = "ruby_kml"
|
5
|
+
s.summary = "Generate KML files with ruby"
|
6
|
+
s.email = ""
|
7
|
+
s.homepage = "http://github.com/schleyfox/ruby_kml"
|
8
|
+
s.description = "Generate KML files with ruby"
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.authors = ["aeden, schleyfox, xaviershay, andykram, IanVaughan"]
|
11
|
+
s.files = Dir['**/**']
|
12
|
+
s.add_dependency('nokogiri')
|
13
|
+
s.add_dependency('builder')
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<kml xmlns="http://earth.google.com/kml/2.1">
|
3
|
+
<Document>
|
4
|
+
<name>Document with CDATA example</name>
|
5
|
+
<Snippet>Document level snippet2</Snippet>
|
6
|
+
<Placemark>
|
7
|
+
<name>CDATA example</name>
|
8
|
+
<description>
|
9
|
+
<![CDATA[<h1>CDATA Tags are useful!</h1>
|
10
|
+
<p><font color="red">Text is <i>more readable</i> and
|
11
|
+
<b>easier to write</b> when you can avoid using entity
|
12
|
+
references.</font></p>
|
13
|
+
]]>
|
14
|
+
</description>
|
15
|
+
<Snippet>Example of a snippet2</Snippet>
|
16
|
+
<Point>
|
17
|
+
<coordinates>-122.0822035425683,37.4228,0</coordinates>
|
18
|
+
</Point>
|
19
|
+
</Placemark>
|
20
|
+
</Document>
|
21
|
+
</kml>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<kml xmlns="http://earth.google.com/kml/2.1">
|
3
|
+
<Folder>
|
4
|
+
<name>Ground Overlays</name>
|
5
|
+
<description>
|
6
|
+
<![CDATA[Examples of ground overlays]]>
|
7
|
+
</description>
|
8
|
+
<GroundOverlay>
|
9
|
+
<name>Large-scale overlay on terrain</name>
|
10
|
+
<description>
|
11
|
+
<![CDATA[Overlay shows Mount Etna erupting on July 13th, 2001.]]>
|
12
|
+
</description>
|
13
|
+
<Icon>
|
14
|
+
<href>http://code.google.com/apis/kml/documentation/etna.jpg</href>
|
15
|
+
</Icon>
|
16
|
+
<LatLonBox>
|
17
|
+
<north>37.91904192681665</north>
|
18
|
+
<south>37.46543388598137</south>
|
19
|
+
<east>15.35832653742206</east>
|
20
|
+
<west>14.60128369746704</west>
|
21
|
+
<rotation/>
|
22
|
+
</LatLonBox>
|
23
|
+
</GroundOverlay>
|
24
|
+
</Folder>
|
25
|
+
</kml>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../test_helper"
|
2
|
+
|
3
|
+
class KML::PointTest < Test::Unit::TestCase
|
4
|
+
include KML
|
5
|
+
|
6
|
+
def test_allows_coordinates_to_be_specified_with_a_hash
|
7
|
+
point = Point.new(:coordinates => {:lat => 10, :lng => 20, :alt => 30})
|
8
|
+
assert_equal [20, 10, 30], point.coordinates
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
class KMLFileTest < Test::Unit::TestCase
|
4
|
+
include KML
|
5
|
+
|
6
|
+
# This also tests the stripping of coordinates
|
7
|
+
def test_placemark
|
8
|
+
kml = KMLFile.new
|
9
|
+
kml.objects << Placemark.new(
|
10
|
+
:name => 'Simple placemark',
|
11
|
+
:description => 'Attached to the ground. Intelligently places itself at the height of the underlying terrain.',
|
12
|
+
:geometry => Point.new(:coordinates=>' -122.0822035425683,37.42228990140251,0 ')
|
13
|
+
)
|
14
|
+
assert_equal File.read('test/simple_placemark.kml'), kml.render
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_cdata_description
|
18
|
+
description = <<-DESC
|
19
|
+
<h1>CDATA Tags are useful!</h1>
|
20
|
+
<p><font color="red">Text is <i>more readable</i> and
|
21
|
+
<b>easier to write</b> when you can avoid using entity
|
22
|
+
references.</font></p>
|
23
|
+
DESC
|
24
|
+
|
25
|
+
kml = KMLFile.new
|
26
|
+
document = Document.new(
|
27
|
+
:name => 'Document with CDATA example',
|
28
|
+
:snippet => Snippet.new("Document level snippet")
|
29
|
+
)
|
30
|
+
document.features << Placemark.new(
|
31
|
+
:name => 'CDATA example',
|
32
|
+
:description => description,
|
33
|
+
:snippet => Snippet.new("Example of a snippet"),
|
34
|
+
:geometry => Point.new(:coordinates=>'-122.0822035425683,37.4228,0')
|
35
|
+
)
|
36
|
+
kml.objects << document
|
37
|
+
assert_equal File.read('test/cdata_and_snippet.kml'), kml.render
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_ground_overlays
|
41
|
+
kml = KMLFile.new
|
42
|
+
folder = Folder.new(
|
43
|
+
:name => 'Ground Overlays',
|
44
|
+
:description => 'Examples of ground overlays'
|
45
|
+
)
|
46
|
+
folder.features << GroundOverlay.new(
|
47
|
+
:name => 'Large-scale overlay on terrain',
|
48
|
+
:description => 'Overlay shows Mount Etna erupting on July 13th, 2001.',
|
49
|
+
:icon => Icon.new(:href => 'http://code.google.com/apis/kml/documentation/etna.jpg'),
|
50
|
+
:lat_lon_box => LatLonBox.new(
|
51
|
+
:north => 37.91904192681665,
|
52
|
+
:south => 37.46543388598137,
|
53
|
+
:east => 15.35832653742206,
|
54
|
+
:west => 14.60128369746704,
|
55
|
+
:rotation => -0.1556640799496235
|
56
|
+
)
|
57
|
+
)
|
58
|
+
kml.objects << folder
|
59
|
+
assert_equal File.read('test/ground_overlays.kml'), kml.render
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_paths
|
63
|
+
kml = KMLFile.new
|
64
|
+
kml.objects << Document.new(
|
65
|
+
:name => 'Paths',
|
66
|
+
:description => 'Examples of paths. Note that the tessellate tag is by default
|
67
|
+
set to 0. If you want to create tessellated lines, they must be authored
|
68
|
+
(or edited) directly in KML.',
|
69
|
+
:styles => [
|
70
|
+
Style.new(
|
71
|
+
:id => 'yellowLineGreenPoly',
|
72
|
+
:line_style => LineStyle.new(:color => '7f00ffff', :width => 4),
|
73
|
+
:poly_style => PolyStyle.new(:color => '7f00ff00')
|
74
|
+
)
|
75
|
+
],
|
76
|
+
:features => [
|
77
|
+
Placemark.new(
|
78
|
+
:name => 'Absolute Extruded',
|
79
|
+
:description => 'Transparent green wall with yellow outlines',
|
80
|
+
:style_url => '#yellowLineGreenPoly',
|
81
|
+
:geometry => LineString.new(
|
82
|
+
:extrude => true,
|
83
|
+
:tessellate => true,
|
84
|
+
:altitude_mode => 'absolute',
|
85
|
+
:coordinates => '-112.2550785337791,36.07954952145647,2357
|
86
|
+
-112.2549277039738,36.08117083492122,2357
|
87
|
+
-112.2552505069063,36.08260761307279,2357
|
88
|
+
-112.2564540158376,36.08395660588506,2357
|
89
|
+
-112.2580238976449,36.08511401044813,2357
|
90
|
+
-112.2595218489022,36.08584355239394,2357
|
91
|
+
-112.2608216347552,36.08612634548589,2357
|
92
|
+
-112.262073428656,36.08626019085147,2357
|
93
|
+
-112.2633204928495,36.08621519860091,2357
|
94
|
+
-112.2644963846444,36.08627897945274,2357
|
95
|
+
-112.2656969554589,36.08649599090644,2357'
|
96
|
+
)
|
97
|
+
)
|
98
|
+
]
|
99
|
+
)
|
100
|
+
assert_equal File.read('test/paths.kml'), kml.render
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_polygon
|
104
|
+
kml = KMLFile.new
|
105
|
+
kml.objects << Placemark.new(
|
106
|
+
:name => 'The Pentagon',
|
107
|
+
:geometry => Polygon.new(
|
108
|
+
:extrude => true,
|
109
|
+
:altitude_mode => 'relativeToGround',
|
110
|
+
:outer_boundary_is => LinearRing.new(
|
111
|
+
:coordinates => '-77.05788457660967,38.87253259892824,100
|
112
|
+
-77.05465973756702,38.87291016281703,100
|
113
|
+
-77.05315536854791,38.87053267794386,100
|
114
|
+
-77.05552622493516,38.868757801256,100
|
115
|
+
-77.05844056290393,38.86996206506943,100
|
116
|
+
-77.05788457660967,38.87253259892824,100'
|
117
|
+
),
|
118
|
+
:inner_boundary_is => LinearRing.new(
|
119
|
+
:coordinates => '-77.05668055019126,38.87154239798456,100
|
120
|
+
-77.05542625960818,38.87167890344077,100
|
121
|
+
-77.05485125901024,38.87076535397792,100
|
122
|
+
-77.05577677433152,38.87008686581446,100
|
123
|
+
-77.05691162017543,38.87054446963351,100
|
124
|
+
-77.05668055019126,38.87154239798456,100'
|
125
|
+
)
|
126
|
+
)
|
127
|
+
)
|
128
|
+
assert_equal File.read('test/polygon.kml'), kml.render
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_polygon_with_multiple_inner_boundaries
|
132
|
+
kml = KMLFile.new
|
133
|
+
kml.objects << Placemark.new(
|
134
|
+
:name => 'The Pentagon',
|
135
|
+
:geometry => Polygon.new(
|
136
|
+
:extrude => true,
|
137
|
+
:altitude_mode => 'relativeToGround',
|
138
|
+
:outer_boundary_is => LinearRing.new(
|
139
|
+
:coordinates => '-77.05788457660967,38.87253259892824,100
|
140
|
+
-77.05465973756702,38.87291016281703,100
|
141
|
+
-77.05315536854791,38.87053267794386,100
|
142
|
+
-77.05552622493516,38.868757801256,100
|
143
|
+
-77.05844056290393,38.86996206506943,100
|
144
|
+
-77.05788457660967,38.87253259892824,100'
|
145
|
+
),
|
146
|
+
:inner_boundary_is => [
|
147
|
+
LinearRing.new(
|
148
|
+
:coordinates => '-77.05668055019126,38.87154239798456,100
|
149
|
+
-77.05542625960818,38.87167890344077,100
|
150
|
+
-77.05485125901024,38.87076535397792,100
|
151
|
+
-77.05577677433152,38.87008686581446,100
|
152
|
+
-77.05691162017543,38.87054446963351,100
|
153
|
+
-77.05668055019126,38.87154239798456,100'
|
154
|
+
),
|
155
|
+
LinearRing.new(
|
156
|
+
:coordinates => '-77.05668055019126,38.87154239798456,100
|
157
|
+
-77.05542625960818,38.87167890344077,100
|
158
|
+
-77.05485125901024,38.87076535397792,100
|
159
|
+
-77.05577677433152,38.87008686581446,100
|
160
|
+
-77.05691162017543,38.87054446963351,100
|
161
|
+
-77.05668055019126,38.87154239798456,100'
|
162
|
+
)
|
163
|
+
]
|
164
|
+
)
|
165
|
+
)
|
166
|
+
assert_equal File.read('test/polygon_inner.kml'), kml.render
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_geometry_styles
|
170
|
+
kml = KMLFile.new
|
171
|
+
kml.objects << Style.new(
|
172
|
+
:id => "transBluePoly",
|
173
|
+
:line_style => LineStyle.new(
|
174
|
+
:width => 1.5
|
175
|
+
),
|
176
|
+
:poly_style => PolyStyle.new(
|
177
|
+
:color => '7dff0000'
|
178
|
+
)
|
179
|
+
)
|
180
|
+
kml.objects << Placemark.new(
|
181
|
+
:name => 'Building 41',
|
182
|
+
:style_url => '#transBluePoly',
|
183
|
+
:geometry => Polygon.new(
|
184
|
+
:extrude => true,
|
185
|
+
:altitude_mode => 'relativeToGround',
|
186
|
+
:outer_boundary_is => LinearRing.new(
|
187
|
+
:coordinates => '-122.0857412771483,37.42227033155257,17
|
188
|
+
-122.0858169768481,37.42231408832346,17
|
189
|
+
-122.085852582875,37.42230337469744,17
|
190
|
+
-122.0858799945639,37.42225686138789,17
|
191
|
+
-122.0858860101409,37.4222311076138,17
|
192
|
+
-122.0858069157288,37.42220250173855,17
|
193
|
+
-122.0858379542653,37.42214027058678,17
|
194
|
+
-122.0856732640519,37.42208690214408,17
|
195
|
+
-122.0856022926407,37.42214885429042,17
|
196
|
+
-122.0855902778436,37.422128290487,17
|
197
|
+
-122.0855841672237,37.42208171967246,17
|
198
|
+
-122.0854852065741,37.42210455874995,17
|
199
|
+
-122.0855067264352,37.42214267949824,17
|
200
|
+
-122.0854430712915,37.42212783846172,17
|
201
|
+
-122.0850990714904,37.42251282407603,17
|
202
|
+
-122.0856769818632,37.42281815323651,17
|
203
|
+
-122.0860162273783,37.42244918858722,17
|
204
|
+
-122.0857260327004,37.42229239604253,17
|
205
|
+
-122.0857412771483,37.42227033155257,17'
|
206
|
+
)
|
207
|
+
)
|
208
|
+
)
|
209
|
+
|
210
|
+
assert_equal File.read('test/polygon_style.kml'), kml.render
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_style_map
|
214
|
+
kml = KMLFile.new
|
215
|
+
kml.objects << Document.new(
|
216
|
+
:name => 'Highlighted Icon',
|
217
|
+
:description => 'Place your mouse over the icon to see it display the new icon',
|
218
|
+
:styles => [
|
219
|
+
Style.new(
|
220
|
+
:id => "highlightPlacemark",
|
221
|
+
:icon_style => IconStyle.new(
|
222
|
+
:icon => Icon.new(
|
223
|
+
:href => "http://maps.google.com/mapfiles/kml/paddle/red-stars.png"
|
224
|
+
)
|
225
|
+
)
|
226
|
+
),
|
227
|
+
Style.new(
|
228
|
+
:id => "normalPlacemark",
|
229
|
+
:icon_style => IconStyle.new(
|
230
|
+
:icon => Icon.new(
|
231
|
+
:href => "http://maps.google.com/mapfiles/kml/paddle/wht-blank.png"
|
232
|
+
)
|
233
|
+
)
|
234
|
+
),
|
235
|
+
StyleMap.new(
|
236
|
+
:id => 'exampleStyleMap',
|
237
|
+
:pairs => {
|
238
|
+
'normal' => '#normalPlacemark',
|
239
|
+
'highlight' => '#highlightPlacemark'
|
240
|
+
}
|
241
|
+
)
|
242
|
+
],
|
243
|
+
:features => [
|
244
|
+
Placemark.new(
|
245
|
+
:name => 'Roll over this icon',
|
246
|
+
:style_url => '#exampleStyleMap',
|
247
|
+
:geometry => Point.new(
|
248
|
+
:coordinates => '-122.0856545755255,37.42243077405461,0'
|
249
|
+
)
|
250
|
+
)
|
251
|
+
]
|
252
|
+
)
|
253
|
+
assert_equal File.read('test/style_map.kml'), kml.render
|
254
|
+
end
|
255
|
+
end
|