kamelopard 0.0.14 → 0.0.15
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.
- checksums.yaml +15 -0
- data/lib/kamelopard/classes.rb +69 -7
- data/lib/kamelopard/geocode.rb +57 -16
- data/lib/kamelopard/helpers.rb +834 -720
- data/lib/kamelopard/multicamify.rb +2 -0
- data/lib/kamelopard/spline.rb +99 -1
- data/spec/test.rb +2999 -0
- metadata +17 -15
data/spec/test.rb
ADDED
@@ -0,0 +1,2999 @@
|
|
1
|
+
# vim:ts=4:sw=4:et:smartindent:nowrap
|
2
|
+
|
3
|
+
$LOAD_PATH << './lib'
|
4
|
+
require 'kamelopard'
|
5
|
+
require "xml"
|
6
|
+
require 'tempfile'
|
7
|
+
|
8
|
+
include Kamelopard
|
9
|
+
include Kamelopard::Functions
|
10
|
+
|
11
|
+
Kamelopard.set_logger lambda { |lev, mod, msg|
|
12
|
+
STDERR.puts "#{lev} #{mod}: #{msg}"
|
13
|
+
}
|
14
|
+
|
15
|
+
# Namespace array for find_first
|
16
|
+
NS = [
|
17
|
+
"xmlns:http://www.opengis.net/kml/2.2",
|
18
|
+
"gx:http://www.google.com/kml/ext/2.2",
|
19
|
+
"kml:http://www.opengis.net/kml/2.2",
|
20
|
+
"atom:http://www.w3.org/2005/Atom"
|
21
|
+
]
|
22
|
+
|
23
|
+
# Printing debug information.
|
24
|
+
def put_info(str)
|
25
|
+
puts
|
26
|
+
puts "="*60
|
27
|
+
puts str
|
28
|
+
puts "*"*60
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Returns the first node found in given doc using given xpath.
|
33
|
+
#
|
34
|
+
#
|
35
|
+
def find_first_kml(doc, xpath)
|
36
|
+
doc.find_first xpath, "kml:http://www.opengis.net/kml/2.2"
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
#
|
41
|
+
# Returns the first node found among children with given name.
|
42
|
+
#
|
43
|
+
#
|
44
|
+
def get_child(node, name)
|
45
|
+
a = nil
|
46
|
+
node.children.each { |child|
|
47
|
+
if child.name == name
|
48
|
+
a = child
|
49
|
+
break
|
50
|
+
end
|
51
|
+
}
|
52
|
+
return a
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Returns the content of the first node found among children with given name.
|
57
|
+
#
|
58
|
+
#
|
59
|
+
def get_child_content(node, name)
|
60
|
+
n = node.children.detect{ |child| child.name == name}
|
61
|
+
n.content unless n.nil?
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Returns the first child with given name.
|
66
|
+
#
|
67
|
+
# On the object param there used to_kml method for getting the kml.
|
68
|
+
#
|
69
|
+
def get_obj_child(object, name)
|
70
|
+
k = object.to_kml
|
71
|
+
get_child(k, name)
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Returns the content of the first child with given name.
|
76
|
+
#
|
77
|
+
# On the object param there used to_kml method for getting the kml.
|
78
|
+
#
|
79
|
+
def get_obj_child_content(object, name)
|
80
|
+
k = object.to_kml
|
81
|
+
get_child_content(k, name)
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Builds proper kml from given node. It surrounds kml from given node with kml tag.
|
86
|
+
# This must be done for using xpath with libxml. If you want to use xpath, then the
|
87
|
+
# node need to belong to a proper libxml document, so we need a proper xml.
|
88
|
+
#
|
89
|
+
def build_doc_from_node(node)
|
90
|
+
kml =<<DOCFROMENODE
|
91
|
+
<kml xmlns="http://www.opengis.net/kml/2.2"
|
92
|
+
xmlns:gx="http://www.google.com/kml/ext/2.2"
|
93
|
+
xmlns:kml="http://www.opengis.net/kml/2.2"
|
94
|
+
xmlns:atom="http://www.w3.org/2005/Atom"
|
95
|
+
xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
|
96
|
+
#{node.to_kml.to_s}
|
97
|
+
</kml>
|
98
|
+
DOCFROMENODE
|
99
|
+
doc = XML::Document.string(kml)
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def test_lat_lon_quad(d, n)
|
104
|
+
get_child_content(d, 'coordinates').should == "#{n},#{n} #{n},#{n} #{n},#{n} #{n},#{n}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_lat_lon_box(l, latlon)
|
108
|
+
get_child_content(l, 'north').should == latlon.north.to_s
|
109
|
+
get_child_content(l, 'south').should == latlon.south.to_s
|
110
|
+
get_child_content(l, 'east').should == latlon.east.to_s
|
111
|
+
get_child_content(l, 'west').should == latlon.west.to_s
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_lod(d, lodval)
|
115
|
+
%w[ minLodPixels maxLodPixels minFadeExtent maxFadeExtent ].each do |f|
|
116
|
+
get_child_content(d, "#{f}").to_i.should == lodval
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def check_kml_values(o, values)
|
121
|
+
values.each do |k, v|
|
122
|
+
o.method("#{k}=").call(v)
|
123
|
+
doc = build_doc_from_node o
|
124
|
+
found = find_first_kml doc, "//kml:#{k}"
|
125
|
+
found.should_not be_nil
|
126
|
+
found.content.should == v.to_s
|
127
|
+
# get_obj_child_content(o, k).should == v.to_s
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def fields_exist(o, fields)
|
132
|
+
fields.each do |f|
|
133
|
+
o.should respond_to(f.to_sym)
|
134
|
+
o.should respond_to("#{f}=".to_sym)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def match_view_vol(x, e)
|
139
|
+
%w[ near rightFov topFov ].each do |a|
|
140
|
+
get_child_content(x, a).to_i.should == e
|
141
|
+
end
|
142
|
+
%w[ leftFov bottomFov ].each do |a|
|
143
|
+
get_child_content(x, a).to_i.should == -e
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def match_image_pyramid(x, e)
|
148
|
+
%w[ tileSize maxWidth maxHeight gridOrigin ].each do |a|
|
149
|
+
get_child_content(x, a).to_i.should == e
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def validate_abstractview(k, type, point, heading, tilt, roll, range, mode)
|
154
|
+
[
|
155
|
+
[ k.name != type, "Wrong type #{ k.name }" ],
|
156
|
+
[ get_child_content(k, 'longitude').to_f != point.longitude, 'Wrong longitude' ],
|
157
|
+
[ get_child_content(k, 'longitude').to_f != point.longitude, 'Wrong longitude' ],
|
158
|
+
[ get_child_content(k, 'latitude').to_f != point.latitude, 'Wrong latitude' ],
|
159
|
+
[ get_child_content(k, 'altitude').to_f != point.altitude, 'Wrong altitude' ],
|
160
|
+
[ get_child_content(k, 'heading').to_f != heading, 'Wrong heading' ],
|
161
|
+
[ get_child_content(k, 'tilt').to_f != tilt, 'Wrong tilt' ],
|
162
|
+
[ type == 'Kamelopard::LookAt' && get_child_content(k, 'range').to_f != range, 'Wrong range' ],
|
163
|
+
[ type == 'Kamelopard::Camera' && get_child_content(k, 'roll').to_f != roll, 'Wrong roll' ],
|
164
|
+
[ mode !~ /SeaFloor/ && get_child_content(k, 'altitudeMode') != mode.to_s, 'Wrong altitude mode' ],
|
165
|
+
[ mode =~ /SeaFloor/ && get_child_content(k, 'gx:altitudeMode') != mode.to_s, 'Wrong gx:altitudeMode' ]
|
166
|
+
].each do |a|
|
167
|
+
return [false, a[1]] if a[0]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def get_test_substyles()
|
172
|
+
i = Kamelopard::IconStyle.new({ :href => 'icon' })
|
173
|
+
la = Kamelopard::LabelStyle.new
|
174
|
+
lin = Kamelopard::LineStyle.new
|
175
|
+
p = Kamelopard::PolyStyle.new
|
176
|
+
b = Kamelopard::BalloonStyle.new({ :text => 'balloon' })
|
177
|
+
lis = Kamelopard::ListStyle.new
|
178
|
+
[ i, la, lin, p, b, lis ]
|
179
|
+
end
|
180
|
+
|
181
|
+
def get_test_styles()
|
182
|
+
i, la, lin, p, b, lis = get_test_substyles()
|
183
|
+
|
184
|
+
si = Kamelopard::Style.new({ :icon => i })
|
185
|
+
sl = Kamelopard::Style.new({
|
186
|
+
:icon => i,
|
187
|
+
:label => la,
|
188
|
+
:line => lin,
|
189
|
+
:poly => p,
|
190
|
+
:balloon => b,
|
191
|
+
:list => lis
|
192
|
+
})
|
193
|
+
sm = Kamelopard::StyleMap.new( { :icon => si, :list => sl } )
|
194
|
+
|
195
|
+
si.kml_id = 'icon'
|
196
|
+
sl.kml_id = 'list'
|
197
|
+
sm.kml_id = 'map'
|
198
|
+
|
199
|
+
[ si, sl, sm ]
|
200
|
+
end
|
201
|
+
|
202
|
+
def check_time_primitive(set_var_lambda, get_kml_lambda, xpath)
|
203
|
+
b = '2011-01-01'
|
204
|
+
e = '2011-02-01'
|
205
|
+
w = '2011-01-01'
|
206
|
+
tn = Kamelopard::TimeSpan.new b, e
|
207
|
+
tm = Kamelopard::TimeStamp.new w
|
208
|
+
|
209
|
+
set_var_lambda.call(tn)
|
210
|
+
d = get_kml_lambda.call
|
211
|
+
|
212
|
+
t = get_child d, 'TimeSpan'
|
213
|
+
get_child_content(t, 'begin').should == b
|
214
|
+
get_child_content(t, 'end').should == e
|
215
|
+
|
216
|
+
set_var_lambda.call(tm)
|
217
|
+
d = get_kml_lambda.call
|
218
|
+
t = get_child d, 'TimeStamp'
|
219
|
+
get_child_content(t, 'when').should == w
|
220
|
+
end
|
221
|
+
|
222
|
+
def get_kml_header
|
223
|
+
<<-header
|
224
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
225
|
+
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
|
226
|
+
<Document>
|
227
|
+
header
|
228
|
+
end
|
229
|
+
|
230
|
+
shared_examples_for 'field_producer' do
|
231
|
+
it 'has the right attributes' do
|
232
|
+
fields_exist @o, @fields
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
shared_examples_for 'Kamelopard::Object' do
|
237
|
+
it 'descends from Kamelopard::Object' do
|
238
|
+
@o.kind_of?(Kamelopard::Object).should == true
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'has an id' do
|
242
|
+
@o.kml_id.should_not be_nil
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'allows a comment' do
|
246
|
+
@o.should respond_to(:comment)
|
247
|
+
@o.should respond_to(:comment=)
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'should put its comment in the KML' do
|
251
|
+
@o.comment = 'Look for this string'
|
252
|
+
k = @o.to_kml
|
253
|
+
k.to_s.should =~ /Look for this string/
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should HTML escape comments' do
|
257
|
+
@o.comment = 'Look for << this string'
|
258
|
+
k = @o.to_kml
|
259
|
+
k.to_s.should =~ /Look for << this string/
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'responds to master_only' do
|
263
|
+
@o.should respond_to(:master_only)
|
264
|
+
@o.should respond_to(:master_only=)
|
265
|
+
@o.master_only = true
|
266
|
+
@o.master_only = false
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'returns KML in master mode only when master_only' do
|
270
|
+
@o.master_only = false
|
271
|
+
@o.to_kml.to_s.should_not == ''
|
272
|
+
@o.master_only = true
|
273
|
+
@o.master_only.should be_true
|
274
|
+
@o.to_kml.to_s.should == ''
|
275
|
+
get_document.master_mode = true
|
276
|
+
get_document.master_mode.should be_true
|
277
|
+
@o.to_kml.to_s.should_not == ''
|
278
|
+
get_document.master_mode = false
|
279
|
+
@o.to_kml.to_s.should == ''
|
280
|
+
@o.master_only = false
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'appends itself to arbitrary XML nodes correctly' do
|
284
|
+
# These classes behave differently when XML::Nodes are passed to their to_kml methods
|
285
|
+
skip = %w{Document Feature StyleSelector ColorStyle}
|
286
|
+
|
287
|
+
if ! skip.include?(@o.class.name.gsub(/Kamelopard::/, ''))
|
288
|
+
x = XML::Node.new 'random'
|
289
|
+
count = x.children.size
|
290
|
+
@o.to_kml(x)
|
291
|
+
x.children.size.should == count + 1
|
292
|
+
end
|
293
|
+
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'creates valid Change objects' do
|
297
|
+
# Objects can set @attr_name and @new_value
|
298
|
+
if (! @attr_name.nil? and ! @new_value.nil?) then
|
299
|
+
c = @o.change(@attr_name, @new_value)
|
300
|
+
c.should be_a_kind_of(XML::Node)
|
301
|
+
c.name.should == 'Change'
|
302
|
+
c.first.should_not be_nil
|
303
|
+
c.first.name.should == @o.class.name.gsub(/^Kamelopard::/, '')
|
304
|
+
c.first.attributes[:targetId].should == @o.kml_id
|
305
|
+
c.first.first.name.should == @attr_name.to_s
|
306
|
+
c.first.first.first.text?.should be_true
|
307
|
+
c.first.first.first.to_s.should == @new_value.to_s
|
308
|
+
# ... or they can set @skip_change to avoid this test
|
309
|
+
elsif (! @skip_change.nil? and @skip_change) then
|
310
|
+
# Nothing happens here
|
311
|
+
# ... or they'll get a FAIL
|
312
|
+
else
|
313
|
+
fail "#{@o.class.name} needs to set @skip_change, or @attr_name and @new_value"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
shared_examples_for 'altitudeMode' do
|
319
|
+
it 'uses the right altitudeMode element' do
|
320
|
+
[:absolute, :clampToGround, :relativeToGround].each do |m|
|
321
|
+
@o.altitudeMode = m
|
322
|
+
k = @o.to_kml
|
323
|
+
get_child_content(k, "altitudeMode").should == m.to_s
|
324
|
+
end
|
325
|
+
|
326
|
+
[:clampToSeaFloor, :relativeToSeaFloor].each do |m|
|
327
|
+
@o.altitudeMode = m
|
328
|
+
k = @o.to_kml
|
329
|
+
get_child_content(k, "gx:altitudeMode").should == m.to_s
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
shared_examples_for 'KML_includes_id' do
|
335
|
+
it 'should include the object ID in the KML' do
|
336
|
+
d = @o.to_kml
|
337
|
+
d.attributes['id'].should_not be_nil
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
shared_examples_for 'KML_producer' do
|
342
|
+
it 'should have a to_kml function' do
|
343
|
+
@o.should respond_to(:to_kml)
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'should create a XML document when to_xml is called' do
|
347
|
+
@o.to_kml.class.to_s.should == 'LibXML::XML::Node'
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
shared_examples_for 'Kamelopard::Geometry' do
|
352
|
+
it_should_behave_like 'Kamelopard::Object'
|
353
|
+
|
354
|
+
it 'descends from Kamelopard::Geometry' do
|
355
|
+
@o.kind_of?(Kamelopard::Geometry).should == true
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
shared_examples_for 'Kamelopard::AbstractView' do
|
360
|
+
it_should_behave_like 'Kamelopard::Object'
|
361
|
+
it_should_behave_like 'altitudeMode'
|
362
|
+
it_should_behave_like 'KML_includes_id'
|
363
|
+
it_should_behave_like 'KML_producer'
|
364
|
+
|
365
|
+
it 'descends from Kamelopard::AbstractView' do
|
366
|
+
@o.kind_of?(Kamelopard::AbstractView).should == true
|
367
|
+
end
|
368
|
+
|
369
|
+
it 'accepts viewer options and includes them in the KML' do
|
370
|
+
k = @o.to_kml
|
371
|
+
k.should_not =~ /ViewerOptions/
|
372
|
+
|
373
|
+
@o[:streetview] = true
|
374
|
+
@o[:sunlight] = true
|
375
|
+
@o[:historicalimagery] = true
|
376
|
+
doc = build_doc_from_node(@o)
|
377
|
+
v = doc.find("//ViewerOptions | //gx:ViewerOptions")
|
378
|
+
v.size.should_not == 0
|
379
|
+
v.find(".//gx:option[@name='sunlight',@enabled='true']").should_not == 0
|
380
|
+
v.find(".//gx:option[@name='streetview',@enabled='true']").should_not == 0
|
381
|
+
v.find(".//gx:option[@name='historicalimagery',@enabled='true']").should_not == 0
|
382
|
+
|
383
|
+
@o[:streetview] = false
|
384
|
+
@o[:sunlight] = false
|
385
|
+
@o[:historicalimagery] = false
|
386
|
+
doc = build_doc_from_node(@o)
|
387
|
+
v = doc.find("//ViewerOptions | //gx:ViewerOptions")
|
388
|
+
v.should_not == 0
|
389
|
+
v.find(".//gx:option[@name='sunlight',@enabled='true']").should_not == 0
|
390
|
+
v.find(".//gx:option[@name='streetview',@enabled='true']").should_not == 0
|
391
|
+
v.find(".//gx:option[@name='historicalimagery',@enabled='true']").should_not == 0
|
392
|
+
end
|
393
|
+
|
394
|
+
it 'whines when a strange option is provided' do
|
395
|
+
lambda { @o[:something_strange] = true }.should raise_exception
|
396
|
+
lambda { @o[:streetview] = true }.should_not raise_exception
|
397
|
+
lambda { @o[:sunlight] = true }.should_not raise_exception
|
398
|
+
lambda { @o[:historicalimagery] = true }.should_not raise_exception
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
shared_examples_for 'Kamelopard::CoordinateList' do
|
403
|
+
it 'returns coordinates in its KML' do
|
404
|
+
@o << [[1,2,3], [2,3,4], [3,4,5]]
|
405
|
+
k = @o.to_kml
|
406
|
+
e = get_child(k, 'coordinates')
|
407
|
+
#e = k.elements['//coordinates']
|
408
|
+
#e = k.root if e.nil?
|
409
|
+
e = k if e.nil?
|
410
|
+
|
411
|
+
e.should_not be_nil
|
412
|
+
e.name.should == 'coordinates'
|
413
|
+
e.content.should =~ /1.0,2.0,3.0/
|
414
|
+
e.content.should =~ /2.0,3.0,4.0/
|
415
|
+
e.content.should =~ /3.0,4.0,5.0/
|
416
|
+
end
|
417
|
+
|
418
|
+
describe 'when adding elements' do
|
419
|
+
it 'accepts arrays of arrays' do
|
420
|
+
@o << [[1,2,3], [2,3,4], [3,4,5]]
|
421
|
+
end
|
422
|
+
|
423
|
+
it 'accepts Kamelopard::Points' do
|
424
|
+
@o << Kamelopard::Point.new( 3, 2, 1 )
|
425
|
+
end
|
426
|
+
|
427
|
+
it 'accepts arrays of points' do
|
428
|
+
q = []
|
429
|
+
[[1,2,3], [2,3,4], [3,4,5]].each do |a|
|
430
|
+
q << Kamelopard::Point.new(a[0], a[1], a[2])
|
431
|
+
end
|
432
|
+
@o << q
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'accepts another Kamelopard::CoordinateList' do
|
436
|
+
p = Kamelopard::LinearRing.new([[1,2,3], [2,3,4], [3,4,5]])
|
437
|
+
@o << p.coordinates
|
438
|
+
end
|
439
|
+
|
440
|
+
it 'complains when trying to add something weird' do
|
441
|
+
a = 42
|
442
|
+
lambda { @o << a }.should raise_error
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
end
|
447
|
+
|
448
|
+
shared_examples_for 'Kamelopard::Camera-like' do
|
449
|
+
it_should_behave_like 'Kamelopard::AbstractView'
|
450
|
+
|
451
|
+
it 'has the right attributes' do
|
452
|
+
fields = %w[ timestamp timespan viewerOptions longitude latitude altitude heading tilt roll altitudeMode ]
|
453
|
+
fields_exist @o, fields
|
454
|
+
end
|
455
|
+
|
456
|
+
it 'contains the right KML attributes' do
|
457
|
+
@o.heading = 12
|
458
|
+
@o.tilt = 12
|
459
|
+
get_obj_child(@o, 'longitude').should_not be_nil
|
460
|
+
get_obj_child(@o, 'latitude').should_not be_nil
|
461
|
+
get_obj_child(@o, 'altitude').should_not be_nil
|
462
|
+
get_obj_child(@o, 'heading').should_not be_nil
|
463
|
+
get_obj_child(@o, 'tilt').should_not be_nil
|
464
|
+
end
|
465
|
+
|
466
|
+
it 'creates a queries.txt entry' do
|
467
|
+
q = @o.to_queries_txt('name', 'planet')
|
468
|
+
q.should_not be_nil
|
469
|
+
q.should match /planet@name@flytoview=/
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
shared_examples_for "Kamelopard::TimePrimitive" do
|
474
|
+
it_should_behave_like 'Kamelopard::Object'
|
475
|
+
it_should_behave_like 'KML_producer'
|
476
|
+
it_should_behave_like 'KML_includes_id'
|
477
|
+
|
478
|
+
it 'descends from Kamelopard::TimePrimitive' do
|
479
|
+
@o.kind_of?(Kamelopard::TimePrimitive).should == true
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
shared_examples_for 'Kamelopard::Feature' do
|
484
|
+
def document_has_styles(d)
|
485
|
+
doc = build_doc_from_node d
|
486
|
+
|
487
|
+
si = find_first_kml doc, "//kml:Style[@id='icon']"
|
488
|
+
raise 'Could not find iconstyle' if si.nil?
|
489
|
+
|
490
|
+
sl = find_first_kml doc, "//kml:Style[@id='list']"
|
491
|
+
raise 'Could not find liststyle' if sl.nil?
|
492
|
+
|
493
|
+
sm = find_first_kml doc, "//kml:StyleMap[@id='map']"
|
494
|
+
raise 'Could not find stylemap' if sm.nil?
|
495
|
+
|
496
|
+
si = find_first_kml doc, "//kml:StyleMap/kml:Pair/kml:Style[@id='icon']"
|
497
|
+
raise 'Could not find iconstyle in stylemap' if si.nil?
|
498
|
+
|
499
|
+
sl = find_first_kml doc, '//kml:StyleMap/kml:Pair/kml:Style[@id="list"]'
|
500
|
+
raise 'Could not find liststyle in stylemap' if sl.nil?
|
501
|
+
true
|
502
|
+
end
|
503
|
+
|
504
|
+
it_should_behave_like 'Kamelopard::Object'
|
505
|
+
it_should_behave_like 'KML_includes_id'
|
506
|
+
it_should_behave_like 'KML_producer'
|
507
|
+
|
508
|
+
it 'descends from Kamelopard::Feature' do
|
509
|
+
@o.kind_of?(Kamelopard::Feature).should == true
|
510
|
+
end
|
511
|
+
|
512
|
+
it 'has the right attributes' do
|
513
|
+
fields = %w[
|
514
|
+
visibility open atom_author atom_link name
|
515
|
+
phoneNumber snippet_text maxLines description abstractView
|
516
|
+
timestamp timespan styleUrl styleSelector region metadata
|
517
|
+
extendedData styles
|
518
|
+
]
|
519
|
+
fields_exist @o, fields
|
520
|
+
|
521
|
+
@o.should respond_to(:addressDetails)
|
522
|
+
end
|
523
|
+
|
524
|
+
it 'handles extended data correctly' do
|
525
|
+
ed = []
|
526
|
+
{
|
527
|
+
'foo' => 'bar',
|
528
|
+
'baz' => 'qux'
|
529
|
+
}.each do |k, v|
|
530
|
+
ed << Kamelopard::Data.new(k, v)
|
531
|
+
end
|
532
|
+
@o.extendedData = ed
|
533
|
+
end
|
534
|
+
|
535
|
+
it 'handles show and hide methods correctly' do
|
536
|
+
@o.hide
|
537
|
+
get_obj_child_content(@o, 'visibility').to_i.should == 0
|
538
|
+
@o.show
|
539
|
+
get_obj_child_content(@o, 'visibility').to_i.should == 1
|
540
|
+
end
|
541
|
+
|
542
|
+
it 'handles extended address stuff correctly' do
|
543
|
+
@o.addressDetails = 'These are some extended details'
|
544
|
+
(get_kml_string =~ /xmlns:xal/).should be_true
|
545
|
+
get_obj_child_content(@o, 'xal:AddressDetails').should == @o.addressDetails
|
546
|
+
end
|
547
|
+
|
548
|
+
it 'handles styles correctly' do
|
549
|
+
get_test_styles().each do |s|
|
550
|
+
@o.styleUrl = s
|
551
|
+
get_obj_child_content(@o, 'styleUrl').should == "##{s.kml_id}"
|
552
|
+
end
|
553
|
+
@o.styleUrl = '#random'
|
554
|
+
get_obj_child_content(@o, 'styleUrl').should == "#random"
|
555
|
+
end
|
556
|
+
|
557
|
+
it 'returns style KML correctly' do
|
558
|
+
get_test_styles().each do |s|
|
559
|
+
@o.styles << s
|
560
|
+
end
|
561
|
+
|
562
|
+
header = get_kml_header
|
563
|
+
|
564
|
+
document_has_styles(@o).should == true
|
565
|
+
end
|
566
|
+
|
567
|
+
it 'returns the right KML for simple fields' do
|
568
|
+
marker = 'Look for this string'
|
569
|
+
fields = %w( name address phoneNumber description styleUrl )
|
570
|
+
fields.each do |f|
|
571
|
+
p = Kamelopard::Feature.new
|
572
|
+
Kamelopard::DocumentHolder.instance.current_document.folder << p
|
573
|
+
p.instance_variable_set("@#{f}".to_sym, marker)
|
574
|
+
e = get_obj_child p, "#{f}"
|
575
|
+
e.should_not be_nil
|
576
|
+
e.content.should == marker
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
it 'returns the right KML for more complex fields' do
|
581
|
+
marker = 'Look for this string'
|
582
|
+
[
|
583
|
+
[ :@addressDetails, 'xal:AddressDetails' ],
|
584
|
+
[ :@metadata, 'Metadata' ],
|
585
|
+
[ :@atom_link, 'atom:link' ]
|
586
|
+
].each do |a|
|
587
|
+
p = Kamelopard::Feature.new
|
588
|
+
p.instance_variable_set(a[0], marker)
|
589
|
+
e = get_child p.to_kml, a[1]
|
590
|
+
e.should_not be_nil
|
591
|
+
e.content.should == marker
|
592
|
+
end
|
593
|
+
end
|
594
|
+
#TODO: investigate why the field atom:author is missing
|
595
|
+
|
596
|
+
it 'correctly KML-ifies the atom:author field' do
|
597
|
+
o = Kamelopard::Feature.new
|
598
|
+
marker = 'Look for this text'
|
599
|
+
o.atom_author = marker
|
600
|
+
doc = build_doc_from_node o
|
601
|
+
doc.find_first('//atom:author/atom:name').content.should == marker
|
602
|
+
end
|
603
|
+
|
604
|
+
it 'returns the right KML for boolean fields' do
|
605
|
+
%w( visibility open ).each do |k|
|
606
|
+
[false, true].each do |v|
|
607
|
+
o = Kamelopard::Feature.new
|
608
|
+
o.instance_variable_set("@#{k}".to_sym, v)
|
609
|
+
get_obj_child_content(o, "#{k}").to_i.should == (v ? 1 : 0)
|
610
|
+
end
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
it 'correctly KML\'s the Kamelopard::Snippet' do
|
615
|
+
maxLines = 2
|
616
|
+
text = "This is my snippet\nIt's more than two lines long.\nNo, really."
|
617
|
+
|
618
|
+
@o.maxLines = maxLines
|
619
|
+
@o.snippet_text = text
|
620
|
+
doc = build_doc_from_node @o
|
621
|
+
s = doc.find_first("//kml:Snippet[@maxLines='#{maxLines}']", 'kml:http://www.opengis.net/kml/2.2')
|
622
|
+
s.should_not be_nil
|
623
|
+
s.content.should == text
|
624
|
+
end
|
625
|
+
|
626
|
+
describe 'correctly produces Kamelopard::Region KML' do
|
627
|
+
before(:all) do
|
628
|
+
@o = Kamelopard::Feature.new({ :name => 'my feature' })
|
629
|
+
@latlon = Kamelopard::LatLonBox.new( 1, -1, 1, -1, 10 )
|
630
|
+
@lod = Kamelopard::Lod.new(128, 1024, 128, 128)
|
631
|
+
@r = Kamelopard::Region.new({ :latlonaltbox => @latlon, :lod => @lod })
|
632
|
+
@o.region = @r
|
633
|
+
|
634
|
+
@reg = get_obj_child(@o, 'Region')
|
635
|
+
@l = get_child(@reg, 'LatLonAltBox')
|
636
|
+
@ld = get_child(@reg, 'Lod')
|
637
|
+
end
|
638
|
+
|
639
|
+
it 'creates a Kamelopard::Region element' do
|
640
|
+
@reg.should_not be_nil
|
641
|
+
@reg['id'].should =~ /^Region_\d+$/
|
642
|
+
end
|
643
|
+
|
644
|
+
it 'creates the right LatLonAltBox' do
|
645
|
+
@l.should_not be_nil
|
646
|
+
test_lat_lon_box(@l, @latlon)
|
647
|
+
end
|
648
|
+
|
649
|
+
it 'creates the right LOD' do
|
650
|
+
@ld.should_not be_nil
|
651
|
+
get_child_content(@ld, 'minLodPixels'). should == @lod.minpixels.to_s
|
652
|
+
get_child_content(@ld, 'maxLodPixels'). should == @lod.maxpixels.to_s
|
653
|
+
get_child_content(@ld, 'minFadeExtent'). should == @lod.minfade.to_s
|
654
|
+
get_child_content(@ld, 'maxFadeExtent'). should == @lod.maxfade.to_s
|
655
|
+
end
|
656
|
+
|
657
|
+
end
|
658
|
+
|
659
|
+
it 'correctly KML\'s the Kamelopard::StyleSelector' do
|
660
|
+
@o = Kamelopard::Feature.new({ :name => 'StyleSelector test' })
|
661
|
+
get_test_styles.each do |s| @o.styles << s end
|
662
|
+
document_has_styles(@o).should == true
|
663
|
+
end
|
664
|
+
|
665
|
+
it 'correctly KML\'s the Kamelopard::TimePrimitive' do
|
666
|
+
@o.timeprimitive = Kamelopard::TimeStamp.new('dflkj')
|
667
|
+
check_time_primitive(
|
668
|
+
lambda { |t| @o.timeprimitive = t },
|
669
|
+
lambda { @o.to_kml },
|
670
|
+
''
|
671
|
+
)
|
672
|
+
end
|
673
|
+
|
674
|
+
it 'correctly KML\'s the Kamelopard::AbstractView' do
|
675
|
+
long, lat, alt = 13, 12, 11
|
676
|
+
heading, tilt, roll, range, mode = 1, 2, 3, 4, :clampToSeaFloor
|
677
|
+
p = Kamelopard::Point.new long, lat, alt
|
678
|
+
camera = Kamelopard::Camera.new(p, {
|
679
|
+
:heading => heading,
|
680
|
+
:tilt => tilt,
|
681
|
+
:roll => roll
|
682
|
+
})
|
683
|
+
lookat = Kamelopard::LookAt.new(p, {
|
684
|
+
:heading => heading,
|
685
|
+
:tilt => tilt,
|
686
|
+
:range => range
|
687
|
+
})
|
688
|
+
@o.abstractView = camera
|
689
|
+
a = get_obj_child(@o, "Camera")
|
690
|
+
a.should_not be_nil
|
691
|
+
validate_abstractview(a, 'Camera', p, heading, tilt, roll, range, mode).should be_true
|
692
|
+
@o.abstractView = lookat
|
693
|
+
a = get_obj_child(@o, "LookAt")
|
694
|
+
a.should_not be_nil
|
695
|
+
validate_abstractview(a, 'LookAt', p, heading, tilt, roll, range, mode).should be_true
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
shared_examples_for 'Kamelopard::Container' do
|
700
|
+
it 'should handle <<' do
|
701
|
+
@o.should respond_to('<<')
|
702
|
+
end
|
703
|
+
end
|
704
|
+
|
705
|
+
shared_examples_for 'Kamelopard::ColorStyle' do
|
706
|
+
it_should_behave_like 'Kamelopard::Object'
|
707
|
+
it_should_behave_like 'KML_includes_id'
|
708
|
+
it_should_behave_like 'KML_producer'
|
709
|
+
|
710
|
+
it 'should accept only valid color modes' do
|
711
|
+
@o.colorMode = :normal
|
712
|
+
@o.colorMode = :random
|
713
|
+
begin
|
714
|
+
@o.colorMode = :something_wrong
|
715
|
+
rescue RuntimeError => f
|
716
|
+
q = f.to_s
|
717
|
+
end
|
718
|
+
q.should =~ /colorMode must be either/
|
719
|
+
end
|
720
|
+
|
721
|
+
it 'should allow setting and retrieving alpha, blue, green, and red' do
|
722
|
+
a = 'ab'
|
723
|
+
@o.alpha = a
|
724
|
+
@o.alpha.should == a
|
725
|
+
@o.blue = a
|
726
|
+
@o.blue.should == a
|
727
|
+
@o.green = a
|
728
|
+
@o.green.should == a
|
729
|
+
@o.red = a
|
730
|
+
@o.red.should == a
|
731
|
+
end
|
732
|
+
|
733
|
+
it 'should get settings in the right order' do
|
734
|
+
@o.alpha = 'de'
|
735
|
+
@o.blue = 'ad'
|
736
|
+
@o.green = 'be'
|
737
|
+
@o.red = 'ef'
|
738
|
+
@o.color.should == 'deadbeef'
|
739
|
+
end
|
740
|
+
|
741
|
+
it 'should do its KML right' do
|
742
|
+
color = 'abcdefab'
|
743
|
+
colorMode = :random
|
744
|
+
@o.color = color
|
745
|
+
@o.colorMode = colorMode
|
746
|
+
get_obj_child_content(@o, 'color').should == color
|
747
|
+
get_obj_child_content(@o, 'colorMode').should == colorMode.to_s
|
748
|
+
end
|
749
|
+
end
|
750
|
+
|
751
|
+
shared_examples_for 'StyleSelector' do
|
752
|
+
it_should_behave_like 'Kamelopard::Object'
|
753
|
+
it_should_behave_like 'KML_producer'
|
754
|
+
it_should_behave_like 'KML_includes_id'
|
755
|
+
|
756
|
+
it 'should handle being attached to stuff' do
|
757
|
+
@o.should respond_to(:attach)
|
758
|
+
p = Kamelopard::Placemark.new({
|
759
|
+
:geometry => Kamelopard::Point.new(123, 23),
|
760
|
+
:name => 'test'
|
761
|
+
})
|
762
|
+
@o.attach(p)
|
763
|
+
@o.attached?.should be_true
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
shared_examples_for 'KML_root_name' do
|
768
|
+
it 'should have the right namespace and root' do
|
769
|
+
d = @o.to_kml
|
770
|
+
if ! @ns.nil? then
|
771
|
+
ns_url = 'http://www.google.com/kml/ext/2.2'
|
772
|
+
# TODO
|
773
|
+
# There is no add_namespace method
|
774
|
+
# d.add_namespace @ns, ns_url
|
775
|
+
# d.root.namespace.should == ns_url
|
776
|
+
end
|
777
|
+
# d.name.should == @o.class.name.gsub('Kamelopard::', '')
|
778
|
+
end
|
779
|
+
end
|
780
|
+
|
781
|
+
shared_examples_for 'Kamelopard::TourPrimitive' do
|
782
|
+
before(:each) do
|
783
|
+
@ns = 'gx'
|
784
|
+
end
|
785
|
+
|
786
|
+
it_should_behave_like 'Kamelopard::Object'
|
787
|
+
it_should_behave_like 'KML_includes_id'
|
788
|
+
it_should_behave_like 'KML_producer'
|
789
|
+
it_should_behave_like 'KML_root_name'
|
790
|
+
end
|
791
|
+
|
792
|
+
shared_examples_for 'Kamelopard::Overlay' do
|
793
|
+
it_should_behave_like 'Kamelopard::Feature'
|
794
|
+
|
795
|
+
it 'should have the right KML' do
|
796
|
+
href = 'look for this href'
|
797
|
+
drawOrder = 10
|
798
|
+
color = 'ffffff'
|
799
|
+
|
800
|
+
@o.href = href
|
801
|
+
@o.drawOrder = drawOrder
|
802
|
+
@o.color = color
|
803
|
+
|
804
|
+
x = get_obj_child(@o, "Icon")
|
805
|
+
get_child_content(x, "href").should == href
|
806
|
+
|
807
|
+
get_obj_child_content(@o, "color").should == color
|
808
|
+
get_obj_child_content(@o, "drawOrder").to_i.should == drawOrder
|
809
|
+
|
810
|
+
end
|
811
|
+
end
|
812
|
+
|
813
|
+
describe 'Kamelopard::Point' do
|
814
|
+
before(:each) do
|
815
|
+
@skip_change = true
|
816
|
+
@attrs = { :lat => 12.4, :long => 34.2, :alt => 500 }
|
817
|
+
@fields = %w[ latitude longitude altitude altitudeMode extrude ]
|
818
|
+
@o = Kamelopard::Point.new(@attrs[:long], @attrs[:lat], @attrs[:alt])
|
819
|
+
end
|
820
|
+
|
821
|
+
it_should_behave_like 'KML_includes_id'
|
822
|
+
it_should_behave_like 'Kamelopard::Geometry'
|
823
|
+
it_should_behave_like 'field_producer'
|
824
|
+
|
825
|
+
it 'parses itself correctly' do
|
826
|
+
p = point(1, 2, 3, :clampToGround, true)
|
827
|
+
new_p = Kamelopard::Point.parse(build_doc_from_node(p))
|
828
|
+
new_p.latitude.should == p.latitude
|
829
|
+
new_p.longitude.should == p.longitude
|
830
|
+
new_p.altitude.should == p.altitude
|
831
|
+
new_p.altitudeMode.should == p.altitudeMode
|
832
|
+
new_p.extrude.should == p.extrude
|
833
|
+
end
|
834
|
+
|
835
|
+
it 'accepts different coordinate formats' do
|
836
|
+
coords = [ [ '123D30m12.2s S', '34D56m24.4s E' ],
|
837
|
+
[ '32d10\'23.10" N', -145.3487 ],
|
838
|
+
[ 123.5985745, -45.32487 ] ]
|
839
|
+
coords.each do |a|
|
840
|
+
lambda { Kamelopard::Point.new(a[1], a[0]) }.should_not raise_error
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
# it 'does not accept coordinates that are out of range' do
|
845
|
+
# q = ''
|
846
|
+
# begin
|
847
|
+
# Kamelopard::Point.new(342.32487, 45908.123487)
|
848
|
+
# rescue RuntimeError => f
|
849
|
+
# q = f.to_s
|
850
|
+
# end
|
851
|
+
# q.should =~ /out of range/
|
852
|
+
# end
|
853
|
+
|
854
|
+
describe 'KML output' do
|
855
|
+
it_should_behave_like 'KML_producer'
|
856
|
+
it_should_behave_like 'altitudeMode'
|
857
|
+
|
858
|
+
it 'has the right coordinates' do
|
859
|
+
k = @o.to_kml
|
860
|
+
get_child_content(k, 'coordinates').should == "#{ @attrs[:long] }, #{ @attrs[:lat] }, #{ @attrs[:alt] }"
|
861
|
+
end
|
862
|
+
|
863
|
+
it 'handles extrude properly' do
|
864
|
+
@o.extrude = true
|
865
|
+
k = @o.to_kml
|
866
|
+
get_child_content(k, 'extrude').should == '1'
|
867
|
+
@o.extrude = false
|
868
|
+
k = @o.to_kml
|
869
|
+
get_child_content(k, 'extrude').should == '0'
|
870
|
+
end
|
871
|
+
|
872
|
+
it 'provides the correct short form' do
|
873
|
+
@o.altitudeMode = :clampToSeaFloor
|
874
|
+
@o.extrude = 1
|
875
|
+
k = @o.to_kml(nil, true)
|
876
|
+
get_child_content(k, 'extrude').should be_nil
|
877
|
+
get_child_content(k, 'altitudeMode').should be_nil
|
878
|
+
@o.master_only = true
|
879
|
+
get_child_content(k, 'extrude').should be_nil
|
880
|
+
get_child_content(k, 'altitudeMode').should be_nil
|
881
|
+
@o.master_only = false
|
882
|
+
end
|
883
|
+
end
|
884
|
+
end
|
885
|
+
|
886
|
+
describe 'Kamelopard::LineString' do
|
887
|
+
before(:each) do
|
888
|
+
@skip_change = true
|
889
|
+
@o = Kamelopard::LineString.new([ [1,2,3], [2,3,4], [3,4,5] ])
|
890
|
+
@fields = %w[
|
891
|
+
altitudeOffset extrude tessellate altitudeMode
|
892
|
+
drawOrder longitude latitude altitude
|
893
|
+
]
|
894
|
+
end
|
895
|
+
|
896
|
+
it_should_behave_like 'altitudeMode'
|
897
|
+
it_should_behave_like 'KML_includes_id'
|
898
|
+
it_should_behave_like 'KML_producer'
|
899
|
+
it_should_behave_like 'Kamelopard::Geometry'
|
900
|
+
it_should_behave_like 'Kamelopard::CoordinateList'
|
901
|
+
it_should_behave_like 'field_producer'
|
902
|
+
|
903
|
+
it 'contains the right KML attributes' do
|
904
|
+
@o.altitudeOffset = nil
|
905
|
+
get_obj_child(@o, 'gx:altitudeOffset').should be_nil
|
906
|
+
@o.altitudeOffset = 1
|
907
|
+
get_obj_child(@o, 'gx:altitudeOffset').should_not be_nil
|
908
|
+
@o.extrude = nil
|
909
|
+
get_obj_child(@o, 'extrude').should be_nil
|
910
|
+
@o.extrude = true
|
911
|
+
get_obj_child(@o, 'extrude').should_not be_nil
|
912
|
+
@o.tessellate = nil
|
913
|
+
get_obj_child(@o, 'tessellate').should be_nil
|
914
|
+
@o.tessellate = true
|
915
|
+
get_obj_child(@o, 'tessellate').should_not be_nil
|
916
|
+
@o.drawOrder = nil
|
917
|
+
get_obj_child(@o, 'gx:drawOrder').should be_nil
|
918
|
+
@o.drawOrder = true
|
919
|
+
get_obj_child(@o, 'gx:drawOrder').should_not be_nil
|
920
|
+
end
|
921
|
+
end
|
922
|
+
|
923
|
+
describe 'Kamelopard::LinearRing' do
|
924
|
+
before(:each) do
|
925
|
+
@skip_change = true
|
926
|
+
@o = Kamelopard::LinearRing.new([ [1,2,3], [2,3,4], [3,4,5] ])
|
927
|
+
@fields = %w[ altitudeOffset extrude tessellate altitudeMode ]
|
928
|
+
end
|
929
|
+
|
930
|
+
it_should_behave_like 'altitudeMode'
|
931
|
+
it_should_behave_like 'KML_includes_id'
|
932
|
+
it_should_behave_like 'KML_producer'
|
933
|
+
it_should_behave_like 'Kamelopard::Geometry'
|
934
|
+
it_should_behave_like 'Kamelopard::CoordinateList'
|
935
|
+
it_should_behave_like 'field_producer'
|
936
|
+
|
937
|
+
it 'contains the right KML attributes' do
|
938
|
+
@o.altitudeOffset = nil
|
939
|
+
get_obj_child(@o, 'gx:altitudeOffset').should be_nil
|
940
|
+
@o.altitudeOffset = 1
|
941
|
+
get_obj_child(@o, 'gx:altitudeOffset').should_not be_nil
|
942
|
+
@o.extrude = nil
|
943
|
+
get_obj_child(@o, 'extrude').should be_nil
|
944
|
+
@o.extrude = true
|
945
|
+
get_obj_child(@o, 'extrude').should_not be_nil
|
946
|
+
@o.tessellate = nil
|
947
|
+
get_obj_child(@o, 'tessellate').should be_nil
|
948
|
+
@o.tessellate = true
|
949
|
+
get_obj_child(@o, 'tessellate').should_not be_nil
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
953
|
+
describe "Polygon" do
|
954
|
+
before(:each) do
|
955
|
+
@skip_change = true
|
956
|
+
@l = Kamelopard::LinearRing.new([[1,2,3],[2,3,4],[3,4,5]])
|
957
|
+
@o = Kamelopard::Polygon.new(@l, :inner => [@l])
|
958
|
+
end
|
959
|
+
|
960
|
+
it_should_behave_like 'Kamelopard::Geometry'
|
961
|
+
end
|
962
|
+
|
963
|
+
describe 'Kamelopard::Camera' do
|
964
|
+
before(:each) do
|
965
|
+
@skip_change = true
|
966
|
+
@o = Kamelopard::Camera.new(
|
967
|
+
Kamelopard::Point.new( 123, -123, 123 ),
|
968
|
+
{
|
969
|
+
:heading => 10,
|
970
|
+
:tilt => 10,
|
971
|
+
:roll => 10,
|
972
|
+
:altitudeMode => :clampToGround
|
973
|
+
}
|
974
|
+
)
|
975
|
+
@fields = [ 'roll' ]
|
976
|
+
end
|
977
|
+
|
978
|
+
it_should_behave_like 'Kamelopard::Camera-like'
|
979
|
+
it_should_behave_like 'field_producer'
|
980
|
+
|
981
|
+
it 'contains the right KML attributes' do
|
982
|
+
@o.roll = 12
|
983
|
+
get_obj_child_content(@o, 'roll').should == '12'
|
984
|
+
end
|
985
|
+
end
|
986
|
+
|
987
|
+
describe 'Kamelopard::LookAt' do
|
988
|
+
before(:each) do
|
989
|
+
@skip_change = true
|
990
|
+
@o = Kamelopard::LookAt.new(
|
991
|
+
Kamelopard::Point.new( 123, -123, 123 ),
|
992
|
+
{
|
993
|
+
:heading => 10,
|
994
|
+
:tilt => 10,
|
995
|
+
:range => 10,
|
996
|
+
:altitudeMode => :clampToGround
|
997
|
+
}
|
998
|
+
)
|
999
|
+
@fields = [ 'range' ]
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
it_should_behave_like 'Kamelopard::Camera-like'
|
1003
|
+
it_should_behave_like 'field_producer'
|
1004
|
+
it_should_behave_like 'KML_root_name'
|
1005
|
+
|
1006
|
+
it 'contains the right KML attributes' do
|
1007
|
+
@o.range = 10
|
1008
|
+
get_folder << placemark('test', :geometry => @o)
|
1009
|
+
get_kml.find_first('//range').should_not be_nil
|
1010
|
+
get_obj_child_content(@o, 'range').should == '10'
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
it 'parses itself correctly' do
|
1014
|
+
# XXX Include tests for gx:TimeSpan, gx:TimeStamp, and ViewerOptions elements
|
1015
|
+
l = Kamelopard::LookAt.new(point(12, 12, 12), :heading => 14, :tilt => 13, :range => 11)
|
1016
|
+
new_l = Kamelopard::LookAt.parse(build_doc_from_node(l))
|
1017
|
+
new_l.latitude.should == l.latitude
|
1018
|
+
new_l.longitude.should == l.longitude
|
1019
|
+
new_l.altitude.should == l.altitude
|
1020
|
+
new_l.altitudeMode.should == l.altitudeMode
|
1021
|
+
new_l.heading.should == l.heading
|
1022
|
+
new_l.tilt.should == l.tilt
|
1023
|
+
new_l.range.should == l.range
|
1024
|
+
end
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
describe 'Kamelopard::TimeStamp' do
|
1028
|
+
before(:each) do
|
1029
|
+
@skip_change = true
|
1030
|
+
@when = '01 Dec 1934 12:12:12 PM'
|
1031
|
+
@o = Kamelopard::TimeStamp.new @when
|
1032
|
+
@fields = [ :when ]
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
it_should_behave_like 'Kamelopard::TimePrimitive'
|
1036
|
+
it_should_behave_like 'field_producer'
|
1037
|
+
it_should_behave_like 'KML_root_name'
|
1038
|
+
|
1039
|
+
it 'has the right KML elements' do
|
1040
|
+
doc = build_doc_from_node @o
|
1041
|
+
doc.find("//*/*[when='#{@when}']").should_not == 0
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
it 'behaves correctly when to_kml() gets an XML::Node' do
|
1045
|
+
a = XML::Node.new 'testnode'
|
1046
|
+
@o.to_kml(a)
|
1047
|
+
a.children.first.name.should == 'TimeStamp'
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
it 'adds the correct namespace' do
|
1051
|
+
a = @o.to_kml(nil, 'test')
|
1052
|
+
a.name.should == 'test:TimeStamp'
|
1053
|
+
end
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
describe 'Kamelopard::TimeSpan' do
|
1057
|
+
before(:each) do
|
1058
|
+
@skip_change = true
|
1059
|
+
@begin = '01 Dec 1934 12:12:12 PM'
|
1060
|
+
@end = '02 Dec 1934 12:12:12 PM'
|
1061
|
+
@o = Kamelopard::TimeSpan.new({ :begin => @begin, :end => @end })
|
1062
|
+
@fields = %w[ begin end ]
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
it_should_behave_like 'Kamelopard::TimePrimitive'
|
1066
|
+
it_should_behave_like 'field_producer'
|
1067
|
+
it_should_behave_like 'KML_root_name'
|
1068
|
+
|
1069
|
+
it 'has the right KML elements' do
|
1070
|
+
doc = build_doc_from_node @o
|
1071
|
+
doc.find("//*/*[begin='#{ @begin }']").should_not be_nil
|
1072
|
+
doc.find("//*/*[end='#{ @end }']").should_not be_nil
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
describe 'Kamelopard::Feature' do
|
1077
|
+
before(:each) do
|
1078
|
+
@attr_name = :visibility
|
1079
|
+
@new_value = 1
|
1080
|
+
@o = Kamelopard::Feature.new('Some feature')
|
1081
|
+
@fields = []
|
1082
|
+
end
|
1083
|
+
it_should_behave_like 'Kamelopard::Feature'
|
1084
|
+
|
1085
|
+
it 'responds correctly when to_kml() is passed an XML::Node object' do
|
1086
|
+
a = XML::Node.new 'testnode'
|
1087
|
+
@o.to_kml(a)
|
1088
|
+
a.attributes[:id].should_not be_nil
|
1089
|
+
found = false
|
1090
|
+
a.children.each do |c|
|
1091
|
+
if c.name == 'name'
|
1092
|
+
found = true
|
1093
|
+
break
|
1094
|
+
end
|
1095
|
+
end
|
1096
|
+
found.should be_true
|
1097
|
+
end
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
describe 'Kamelopard::Container' do
|
1101
|
+
before(:each) do
|
1102
|
+
@o = Kamelopard::Container.new
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
it_should_behave_like 'Kamelopard::Container'
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
describe 'Kamelopard::Folder' do
|
1109
|
+
before(:each) do
|
1110
|
+
@skip_change = true
|
1111
|
+
@o = Kamelopard::Folder.new('test folder')
|
1112
|
+
@fields = []
|
1113
|
+
end
|
1114
|
+
it_should_behave_like 'Kamelopard::Container'
|
1115
|
+
it_should_behave_like 'Kamelopard::Feature'
|
1116
|
+
end
|
1117
|
+
|
1118
|
+
describe 'Kamelopard::Document' do
|
1119
|
+
before(:each) do
|
1120
|
+
@skip_change = true
|
1121
|
+
@o = Kamelopard::DocumentHolder.instance.current_document
|
1122
|
+
|
1123
|
+
# Subsequent runs seem to keep the vsr_actions from previous runs, so clear 'em
|
1124
|
+
@o.vsr_actions = []
|
1125
|
+
|
1126
|
+
@lat = Kamelopard.convert_coord('10d10m10.1s N')
|
1127
|
+
@lon = Kamelopard.convert_coord('10d10m10.1s E')
|
1128
|
+
@alt = 1000
|
1129
|
+
@head = 150
|
1130
|
+
|
1131
|
+
@vsractions = %w{a b c d e f}
|
1132
|
+
@vsractions.each do |a|
|
1133
|
+
Kamelopard::VSRAction.new(a, :constraints => {
|
1134
|
+
:latitude => to_constraint(band(@lat, 0.1).collect{ |l| lat_check(l) }),
|
1135
|
+
:longitude => to_constraint(band(@lon, 0.1).collect{ |l| long_check(l) }),
|
1136
|
+
:heading => to_constraint(band(@head, 1)),
|
1137
|
+
:altitude => to_constraint(band(@alt, 2))
|
1138
|
+
})
|
1139
|
+
end
|
1140
|
+
end
|
1141
|
+
|
1142
|
+
it_should_behave_like 'Kamelopard::Container'
|
1143
|
+
it_should_behave_like 'Kamelopard::Feature'
|
1144
|
+
|
1145
|
+
it 'accepts new viewsyncrelay actions' do
|
1146
|
+
Kamelopard::DocumentHolder.instance.current_document.vsr_actions.size.should == @vsractions.size
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
it 'can write its viewsyncrelay actions to a valid YAML string' do
|
1150
|
+
Kamelopard::DocumentHolder.instance.current_document.vsr_actions.size.should == @vsractions.size
|
1151
|
+
act = YAML.load(get_actions)
|
1152
|
+
act['actions'].size.should == @vsractions.size
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
it 'can write its viewsyncrelay actions to a file' do
|
1156
|
+
file = Tempfile.new('kamelopard_test')
|
1157
|
+
file.close
|
1158
|
+
write_actions_to file.path
|
1159
|
+
YAML.parse_file(file.path)
|
1160
|
+
file.unlink
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
it 'should return a tour' do
|
1164
|
+
@o.should respond_to(:tour)
|
1165
|
+
@o.tour.class.should == Kamelopard::Tour
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
it 'should return a folder' do
|
1169
|
+
@o.should respond_to(:folder)
|
1170
|
+
@o.folder.class.should == Kamelopard::Folder
|
1171
|
+
end
|
1172
|
+
|
1173
|
+
it 'should have a get_kml_document method' do
|
1174
|
+
@o.should respond_to(:get_kml_document)
|
1175
|
+
@o.get_kml_document.class.should == LibXML::XML::Document
|
1176
|
+
end
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
describe 'Kamelopard::ColorStyle' do
|
1180
|
+
before(:each) do
|
1181
|
+
@new_value = '11111111'
|
1182
|
+
@attr_name = :color
|
1183
|
+
@o = Kamelopard::ColorStyle.new 'deadbeef'
|
1184
|
+
@o.colorMode = :random
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
it_should_behave_like 'Kamelopard::ColorStyle'
|
1188
|
+
it_should_behave_like 'KML_root_name'
|
1189
|
+
|
1190
|
+
it 'should return the right KML' do
|
1191
|
+
get_obj_child_content(@o, 'color').should == 'deadbeef'
|
1192
|
+
get_obj_child_content(@o, 'colorMode').should == 'random'
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
it 'responds correctly when to_kml() is passed an XML::Node object' do
|
1196
|
+
a = XML::Node.new 'testnode'
|
1197
|
+
@o.to_kml(a)
|
1198
|
+
a.attributes[:id].should_not be_nil
|
1199
|
+
a.children.size.should == 2
|
1200
|
+
|
1201
|
+
sums = {
|
1202
|
+
:color => 0,
|
1203
|
+
:colorMode => 0,
|
1204
|
+
}
|
1205
|
+
a.children.each do |c|
|
1206
|
+
sums[c.name.to_sym] += 1
|
1207
|
+
end
|
1208
|
+
sums.keys.each do |k|
|
1209
|
+
sums[k].should == 1
|
1210
|
+
end
|
1211
|
+
end
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
describe 'Kamelopard::BalloonStyle' do
|
1215
|
+
before(:each) do
|
1216
|
+
@new_value = '11111111'
|
1217
|
+
@attr_name = :color
|
1218
|
+
@o = Kamelopard::BalloonStyle.new 'balloon text'
|
1219
|
+
@o.textColor = 'deadbeef'
|
1220
|
+
@o.bgColor = 'deadbeef'
|
1221
|
+
@o.displayMode = :hide
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
it_should_behave_like 'Kamelopard::Object'
|
1225
|
+
it_should_behave_like 'KML_includes_id'
|
1226
|
+
it_should_behave_like 'KML_producer'
|
1227
|
+
it_should_behave_like 'KML_root_name'
|
1228
|
+
|
1229
|
+
it 'should have the right attributes' do
|
1230
|
+
@o.bgColor.should == 'deadbeef'
|
1231
|
+
@o.textColor.should == 'deadbeef'
|
1232
|
+
@o.displayMode.should == :hide
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
it 'should return the right KML' do
|
1236
|
+
get_obj_child_content(@o, 'text').should == 'balloon text'
|
1237
|
+
get_obj_child_content(@o, 'bgColor').should == 'deadbeef'
|
1238
|
+
get_obj_child_content(@o, 'textColor').should == 'deadbeef'
|
1239
|
+
get_obj_child_content(@o, 'displayMode').should == 'hide'
|
1240
|
+
end
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
describe 'Kamelopard::XY' do
|
1244
|
+
before(:each) do
|
1245
|
+
@x, @y, @xunits, @yunits = 0.2, 13, :fraction, :pixels
|
1246
|
+
@o = Kamelopard::XY.new @x, @y, @xunits, @yunits
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
it 'should return the right KML' do
|
1250
|
+
d = @o.to_kml 'test'
|
1251
|
+
d.name = 'test'
|
1252
|
+
d.attributes['x'].to_f.should == @x
|
1253
|
+
d.attributes['y'].to_f.should == @y
|
1254
|
+
d.attributes['xunits'].to_sym.should == @xunits
|
1255
|
+
d.attributes['yunits'].to_sym.should == @yunits
|
1256
|
+
end
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
shared_examples_for 'Kamelopard::Icon' do
|
1260
|
+
before(:each) do
|
1261
|
+
@href = 'icon href'
|
1262
|
+
@values = {
|
1263
|
+
'href' => @href,
|
1264
|
+
'x' => 1.0,
|
1265
|
+
'y' => 2.0,
|
1266
|
+
'w' => 3.0,
|
1267
|
+
'h' => 4.0,
|
1268
|
+
'refreshMode' => :onInterval,
|
1269
|
+
'refreshInterval' => 4,
|
1270
|
+
'viewRefreshMode' => :onStop,
|
1271
|
+
'viewRefreshTime' => 4,
|
1272
|
+
'viewBoundScale' => 1,
|
1273
|
+
'viewFormat' => 'format',
|
1274
|
+
'httpQuery' => 'query'
|
1275
|
+
}
|
1276
|
+
@fields = @values.keys
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
it_should_behave_like 'KML_includes_id'
|
1280
|
+
it_should_behave_like 'KML_producer'
|
1281
|
+
it_should_behave_like 'field_producer'
|
1282
|
+
|
1283
|
+
it 'puts the right fields in KML' do
|
1284
|
+
@values.each do |f, v|
|
1285
|
+
@o.method("#{f.to_s}=".to_sym).call(v)
|
1286
|
+
kml = @o.to_kml
|
1287
|
+
d = get_obj_child(kml, 'Icon')
|
1288
|
+
elem = f
|
1289
|
+
if f == 'x' || f == 'y' || f == 'w' || f == 'h' then
|
1290
|
+
elem = 'gx:' + f
|
1291
|
+
end
|
1292
|
+
#e = d.elements["//#{elem}"]
|
1293
|
+
e = get_child d, elem
|
1294
|
+
e.should_not be_nil
|
1295
|
+
e.content.should == v.to_s
|
1296
|
+
end
|
1297
|
+
end
|
1298
|
+
end
|
1299
|
+
|
1300
|
+
describe 'Kamelopard::IconStyle' do
|
1301
|
+
before(:each) do
|
1302
|
+
@new_value = '11111111'
|
1303
|
+
@attr_name = :color
|
1304
|
+
@href = 'Kamelopard::IconStyle href'
|
1305
|
+
@scale = 1.0
|
1306
|
+
@heading = 2.0
|
1307
|
+
@hs_x = 0.4
|
1308
|
+
@hs_y = 0.6
|
1309
|
+
@hs_xunits = :fraction
|
1310
|
+
@hs_yunits = :pixels
|
1311
|
+
@color = 'abcdefab'
|
1312
|
+
@colorMode = :random
|
1313
|
+
@o = Kamelopard::IconStyle.new( @href, {
|
1314
|
+
:scale => @scale,
|
1315
|
+
:heading => @heading,
|
1316
|
+
:hs_x => @hs_x,
|
1317
|
+
:hs_y => @hs_y,
|
1318
|
+
:hs_xunits => @hs_xunits,
|
1319
|
+
:hs_yunits => @hs_yunits,
|
1320
|
+
:color => @color,
|
1321
|
+
:colorMode => @colorMode
|
1322
|
+
})
|
1323
|
+
end
|
1324
|
+
|
1325
|
+
it_should_behave_like 'Kamelopard::ColorStyle'
|
1326
|
+
|
1327
|
+
it 'should support the right elements' do
|
1328
|
+
@o.should respond_to(:scale)
|
1329
|
+
@o.should respond_to(:scale=)
|
1330
|
+
@o.should respond_to(:heading)
|
1331
|
+
@o.should respond_to(:heading=)
|
1332
|
+
end
|
1333
|
+
|
1334
|
+
it 'should have the right KML' do
|
1335
|
+
d = @o.to_kml
|
1336
|
+
i = get_child d, "Icon"
|
1337
|
+
get_child_content(i, "href").should == @href
|
1338
|
+
|
1339
|
+
get_child_content(d, "scale").should == @scale.to_s
|
1340
|
+
get_child_content(d, "heading").should == @heading.to_s
|
1341
|
+
|
1342
|
+
h = get_child d, 'hotSpot'
|
1343
|
+
h.attributes['x'].should == @hs_x.to_s
|
1344
|
+
h.attributes['y'].should == @hs_y.to_s
|
1345
|
+
h.attributes['xunits'].should == @hs_xunits.to_s
|
1346
|
+
h.attributes['yunits'].should == @hs_yunits.to_s
|
1347
|
+
end
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
describe 'Kamelopard::LabelStyle' do
|
1351
|
+
before(:each) do
|
1352
|
+
@new_value = '11111111'
|
1353
|
+
@attr_name = :color
|
1354
|
+
@fields = %w[ scale color colorMode ]
|
1355
|
+
@scale = 2
|
1356
|
+
@color = 'abcdefab'
|
1357
|
+
@colorMode = :random
|
1358
|
+
@o = Kamelopard::LabelStyle.new( @scale, {
|
1359
|
+
:color => @color,
|
1360
|
+
:colorMode => @colorMode
|
1361
|
+
})
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
it_should_behave_like 'Kamelopard::ColorStyle'
|
1365
|
+
|
1366
|
+
it 'should have a scale field' do
|
1367
|
+
@o.should respond_to(:scale)
|
1368
|
+
@o.should respond_to(:scale=)
|
1369
|
+
get_obj_child_content(@o, 'scale').to_i.should == @scale
|
1370
|
+
end
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
describe 'Kamelopard::LineStyle' do
|
1374
|
+
before(:each) do
|
1375
|
+
@new_value = '11111111'
|
1376
|
+
@attr_name = :color
|
1377
|
+
@width = 1
|
1378
|
+
@outerColor = 'aaaaaaaa'
|
1379
|
+
@outerWidth = 2
|
1380
|
+
@physicalWidth = 3
|
1381
|
+
@color = 'abcdefab'
|
1382
|
+
@colorMode = :normal
|
1383
|
+
@o = Kamelopard::LineStyle.new({
|
1384
|
+
:width => @width,
|
1385
|
+
:outerColor => @outerColor,
|
1386
|
+
:outerWidth => @outerWidth,
|
1387
|
+
:physicalWidth => @physicalWidth,
|
1388
|
+
:color => @color,
|
1389
|
+
:colorMode => @colorMode
|
1390
|
+
})
|
1391
|
+
@values = {
|
1392
|
+
'width' => @width,
|
1393
|
+
'outerColor' => @outerColor,
|
1394
|
+
'outerWidth' => @outerWidth,
|
1395
|
+
'physicalWidth' => @physicalWidth
|
1396
|
+
}
|
1397
|
+
@fields = @values.keys
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
it_should_behave_like 'Kamelopard::ColorStyle'
|
1401
|
+
it_should_behave_like 'field_producer'
|
1402
|
+
|
1403
|
+
it 'should do its KML right' do
|
1404
|
+
@values.each do |k, v|
|
1405
|
+
@o.method("#{k}=").call(v)
|
1406
|
+
elem = (k == 'width' ? k : "gx:#{k}" )
|
1407
|
+
get_obj_child_content(@o, "#{elem}").should == v.to_s
|
1408
|
+
end
|
1409
|
+
end
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
describe 'Kamelopard::ListStyle' do
|
1413
|
+
before(:each) do
|
1414
|
+
@new_value = '11111111'
|
1415
|
+
@attr_name = :color
|
1416
|
+
@bgColor = 'ffffffff'
|
1417
|
+
@state = :closed
|
1418
|
+
@listItemType = :check
|
1419
|
+
@href = 'list href'
|
1420
|
+
@o = Kamelopard::ListStyle.new({
|
1421
|
+
:bgColor => @bgColor,
|
1422
|
+
:state => @state,
|
1423
|
+
:href => @href,
|
1424
|
+
:listItemType => @listItemType
|
1425
|
+
})
|
1426
|
+
@fields = %w[ bgColor state listItemType href ]
|
1427
|
+
end
|
1428
|
+
|
1429
|
+
it_should_behave_like 'Kamelopard::Object'
|
1430
|
+
it_should_behave_like 'KML_includes_id'
|
1431
|
+
it_should_behave_like 'KML_producer'
|
1432
|
+
it_should_behave_like 'field_producer'
|
1433
|
+
|
1434
|
+
it 'makes the right KML' do
|
1435
|
+
values = {
|
1436
|
+
'href' => @href,
|
1437
|
+
'state' => @state,
|
1438
|
+
'listItemType' => @listItemType,
|
1439
|
+
'bgColor' => @bgColor
|
1440
|
+
}
|
1441
|
+
|
1442
|
+
check_kml_values @o, values
|
1443
|
+
end
|
1444
|
+
end
|
1445
|
+
|
1446
|
+
describe 'Kamelopard::PolyStyle' do
|
1447
|
+
before(:each) do
|
1448
|
+
@attr_name = :color
|
1449
|
+
@new_value = '11111111'
|
1450
|
+
@fill = 1
|
1451
|
+
@outline = 1
|
1452
|
+
@color = 'abcdefab'
|
1453
|
+
@colorMode = :random
|
1454
|
+
@o = Kamelopard::PolyStyle.new({
|
1455
|
+
:fill => @fill,
|
1456
|
+
:outline => @outline,
|
1457
|
+
:color => @color,
|
1458
|
+
:colorMode => @colorMode
|
1459
|
+
})
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
it_should_behave_like 'Kamelopard::ColorStyle'
|
1463
|
+
|
1464
|
+
it 'should have the right fields' do
|
1465
|
+
fields = %w[ fill outline ]
|
1466
|
+
fields_exist @o, fields
|
1467
|
+
end
|
1468
|
+
|
1469
|
+
it 'should do the right KML' do
|
1470
|
+
values = {
|
1471
|
+
'fill' => @fill,
|
1472
|
+
'outline' => @outline
|
1473
|
+
}
|
1474
|
+
check_kml_values @o, values
|
1475
|
+
end
|
1476
|
+
end
|
1477
|
+
|
1478
|
+
describe 'StyleSelector' do
|
1479
|
+
before(:each) do
|
1480
|
+
@skip_change = true
|
1481
|
+
@o = Kamelopard::StyleSelector.new
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
it_should_behave_like 'StyleSelector'
|
1485
|
+
|
1486
|
+
it 'responds correctly when to_kml() is passed an XML::Node object' do
|
1487
|
+
a = XML::Node.new 'testnode'
|
1488
|
+
@o.to_kml(a)
|
1489
|
+
a.attributes[:id].should_not be_nil
|
1490
|
+
end
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
describe 'Style' do
|
1494
|
+
before(:each) do
|
1495
|
+
@skip_change = true
|
1496
|
+
i, la, lin, p, b, lis = get_test_substyles
|
1497
|
+
@o = Kamelopard::Style.new({
|
1498
|
+
:icon => i,
|
1499
|
+
:label => la,
|
1500
|
+
:line => lin,
|
1501
|
+
:poly => p,
|
1502
|
+
:balloon => b,
|
1503
|
+
:list => lis
|
1504
|
+
})
|
1505
|
+
end
|
1506
|
+
|
1507
|
+
it_should_behave_like 'StyleSelector'
|
1508
|
+
|
1509
|
+
it 'should have the right attributes' do
|
1510
|
+
[ :icon, :label, :line, :poly, :balloon, :list ].each do |a|
|
1511
|
+
@o.should respond_to(a)
|
1512
|
+
@o.should respond_to("#{ a.to_s }=".to_sym)
|
1513
|
+
end
|
1514
|
+
end
|
1515
|
+
|
1516
|
+
it 'should have the right KML bits' do
|
1517
|
+
d = @o.to_kml
|
1518
|
+
%w[ IconStyle LabelStyle LineStyle PolyStyle BalloonStyle ListStyle ].each do |e|
|
1519
|
+
get_child(d, e).should_not be_nil
|
1520
|
+
end
|
1521
|
+
end
|
1522
|
+
end
|
1523
|
+
|
1524
|
+
describe 'StyleMap' do
|
1525
|
+
def has_correct_stylemap_kml?(o)
|
1526
|
+
doc = build_doc_from_node o
|
1527
|
+
f = find_first_kml doc, '//kml:StyleMap/kml:Pair[kml:key="normal"]/kml:Style'
|
1528
|
+
s = find_first_kml doc, '//kml:StyleMap/kml:Pair[kml:key="highlight"]/kml:styleUrl'
|
1529
|
+
return f && s
|
1530
|
+
end
|
1531
|
+
|
1532
|
+
before(:each) do
|
1533
|
+
@skip_change = true
|
1534
|
+
i, la, lin, p, b, lis = get_test_substyles
|
1535
|
+
s = Kamelopard::Style.new({
|
1536
|
+
:icon => i,
|
1537
|
+
:balloon => b,
|
1538
|
+
:list => lis
|
1539
|
+
})
|
1540
|
+
@o = Kamelopard::StyleMap.new({ 'normal' => s, 'highlight' => 'someUrl' })
|
1541
|
+
end
|
1542
|
+
|
1543
|
+
it_should_behave_like 'StyleSelector'
|
1544
|
+
|
1545
|
+
it 'should handle styles vs. styleurls correctly' do
|
1546
|
+
has_correct_stylemap_kml?(@o).should be_true
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
it 'should merge right' do
|
1550
|
+
o = Kamelopard::StyleMap.new({ 'normal' => Kamelopard::Style.new })
|
1551
|
+
o.merge( { 'highlight' => 'test2' } )
|
1552
|
+
has_correct_stylemap_kml?(o).should be_true
|
1553
|
+
end
|
1554
|
+
end
|
1555
|
+
|
1556
|
+
describe 'Kamelopard::Placemark' do
|
1557
|
+
before(:each) do
|
1558
|
+
@attr_name = 'gx:balloonVisibility'
|
1559
|
+
@new_value = 1
|
1560
|
+
@p = Kamelopard::Point.new( 123, 123 )
|
1561
|
+
@o = Kamelopard::Placemark.new({
|
1562
|
+
:name => 'placemark',
|
1563
|
+
:geometry => @p
|
1564
|
+
})
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
it_should_behave_like 'Kamelopard::Feature'
|
1568
|
+
|
1569
|
+
it 'supports the right attributes' do
|
1570
|
+
[
|
1571
|
+
:latitude,
|
1572
|
+
:longitude,
|
1573
|
+
:altitude,
|
1574
|
+
:altitudeMode
|
1575
|
+
].each do |f|
|
1576
|
+
@o.should respond_to(f)
|
1577
|
+
end
|
1578
|
+
end
|
1579
|
+
|
1580
|
+
it 'handles returning point correctly' do
|
1581
|
+
o1 = Kamelopard::Placemark.new( 'non-point', {
|
1582
|
+
:geometry => Kamelopard::Object.new
|
1583
|
+
})
|
1584
|
+
o2 = Kamelopard::Placemark.new( 'point', {
|
1585
|
+
:geometry => Kamelopard::Point.new(123, 123)
|
1586
|
+
})
|
1587
|
+
|
1588
|
+
lambda { o1.point }.should raise_exception
|
1589
|
+
lambda { o2.point }.should_not raise_exception
|
1590
|
+
end
|
1591
|
+
end
|
1592
|
+
|
1593
|
+
describe 'Kamelopard::FlyTo' do
|
1594
|
+
before(:each) do
|
1595
|
+
@attr_name = :duration
|
1596
|
+
@new_value = 10
|
1597
|
+
@o = Kamelopard::FlyTo.new
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
it_should_behave_like 'Kamelopard::TourPrimitive'
|
1601
|
+
|
1602
|
+
it 'puts the right stuff in the KML' do
|
1603
|
+
duration = 10
|
1604
|
+
mode = :smooth
|
1605
|
+
@o.duration = duration
|
1606
|
+
@o.mode = mode
|
1607
|
+
get_child_content(@o.to_kml, "gx:duration").should == duration.to_s
|
1608
|
+
get_child_content(@o.to_kml, "gx:flyToMode").should == mode.to_s
|
1609
|
+
end
|
1610
|
+
|
1611
|
+
it 'handles Kamelopard::AbstractView correctly' do
|
1612
|
+
o = Kamelopard::FlyTo.new Kamelopard::LookAt.new( Kamelopard::Point.new(100, 100) )
|
1613
|
+
o.view.class.should == Kamelopard::LookAt
|
1614
|
+
o = Kamelopard::FlyTo.new Kamelopard::Point.new(90, 90)
|
1615
|
+
o.view.class.should == Kamelopard::LookAt
|
1616
|
+
o = Kamelopard::FlyTo.new Kamelopard::Camera.new(Kamelopard::Point.new(90, 90))
|
1617
|
+
o.view.class.should == Kamelopard::Camera
|
1618
|
+
end
|
1619
|
+
end
|
1620
|
+
|
1621
|
+
describe 'Kamelopard::AnimatedUpdate' do
|
1622
|
+
before(:each) do
|
1623
|
+
@skip_change = true
|
1624
|
+
@duration = 10
|
1625
|
+
@target = 'abcd'
|
1626
|
+
@delayedstart = 10
|
1627
|
+
@o = Kamelopard::AnimatedUpdate.new([], {
|
1628
|
+
:duration => @duration, :target => @target, :delayedStart => @delayedstart
|
1629
|
+
})
|
1630
|
+
end
|
1631
|
+
|
1632
|
+
it_should_behave_like 'Kamelopard::TourPrimitive'
|
1633
|
+
|
1634
|
+
it 'allows adding updates' do
|
1635
|
+
@o.updates.size.should == 0
|
1636
|
+
@o << '<Change><Placemark targetId="1"><visibility>1</visibility></Placemark></Change>'
|
1637
|
+
@o << '<Change><Placemark targetId="2"><visibility>0</visibility></Placemark></Change>'
|
1638
|
+
@o.updates.size.should == 2
|
1639
|
+
end
|
1640
|
+
|
1641
|
+
it 'returns the right KML' do
|
1642
|
+
@o.is_a?(Kamelopard::AnimatedUpdate).should == true
|
1643
|
+
@o << '<Change><Placemark targetId="1"><visibility>1</visibility></Placemark></Change>'
|
1644
|
+
d = @o.to_kml
|
1645
|
+
doc = build_doc_from_node @o
|
1646
|
+
find_first_kml(doc, "//kml:Update/kml:targetHref").content.should == @target
|
1647
|
+
find_first_kml(doc, "//kml:Update/kml:Change/kml:Placemark").should_not be_nil
|
1648
|
+
get_child_content(d, "gx:delayedStart").should == @delayedstart.to_s
|
1649
|
+
get_child_content(d, "gx:duration").should == @duration.to_s
|
1650
|
+
|
1651
|
+
|
1652
|
+
# d.elements['//Update/targetHref'].text.should == @target
|
1653
|
+
# d.elements['//Update/Change/Placemark'].should_not be_nil
|
1654
|
+
# d.elements['//gx:delayedStart'].text.to_i.should == @delayedstart
|
1655
|
+
# d.elements['//gx:duration'].text.to_i.should == @duration
|
1656
|
+
end
|
1657
|
+
end
|
1658
|
+
|
1659
|
+
describe 'Kamelopard::TourControl' do
|
1660
|
+
before(:each) do
|
1661
|
+
@skip_change = true
|
1662
|
+
@o = Kamelopard::TourControl.new
|
1663
|
+
end
|
1664
|
+
|
1665
|
+
it_should_behave_like 'Kamelopard::TourPrimitive'
|
1666
|
+
|
1667
|
+
it 'should have the right KML' do
|
1668
|
+
get_obj_child_content(@o, "gx:playMode").should == 'pause'
|
1669
|
+
end
|
1670
|
+
end
|
1671
|
+
|
1672
|
+
describe 'Kamelopard::Wait' do
|
1673
|
+
before(:each) do
|
1674
|
+
@skip_change = true
|
1675
|
+
@pause = 10
|
1676
|
+
@o = Kamelopard::Wait.new(@pause)
|
1677
|
+
end
|
1678
|
+
|
1679
|
+
it_should_behave_like 'Kamelopard::TourPrimitive'
|
1680
|
+
|
1681
|
+
it 'should have the right KML' do
|
1682
|
+
get_obj_child_content(@o, "gx:duration").to_i.should == @pause
|
1683
|
+
end
|
1684
|
+
end
|
1685
|
+
|
1686
|
+
describe 'Kamelopard::SoundCue' do
|
1687
|
+
before(:each) do
|
1688
|
+
@attr_name = :href
|
1689
|
+
@new_value = 'new href'
|
1690
|
+
@href = 'href'
|
1691
|
+
@delayedStart = 10.0
|
1692
|
+
@o = Kamelopard::SoundCue.new @href, @delayedStart
|
1693
|
+
end
|
1694
|
+
|
1695
|
+
it_should_behave_like 'Kamelopard::TourPrimitive'
|
1696
|
+
|
1697
|
+
it 'should have the right KML' do
|
1698
|
+
d = @o.to_kml
|
1699
|
+
get_obj_child_content(@o, "href").should == @href
|
1700
|
+
get_obj_child_content(@o, "gx:delayedStart").to_f.should == @delayedStart
|
1701
|
+
end
|
1702
|
+
end
|
1703
|
+
|
1704
|
+
describe 'Kamelopard::Tour' do
|
1705
|
+
before(:each) do
|
1706
|
+
@skip_change = true
|
1707
|
+
@name = 'TourName'
|
1708
|
+
@description = 'TourDescription'
|
1709
|
+
@o = Kamelopard::Tour.new @name, @description
|
1710
|
+
@ns = 'gx'
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
it_should_behave_like 'Kamelopard::Object'
|
1714
|
+
it_should_behave_like 'KML_includes_id'
|
1715
|
+
it_should_behave_like 'KML_producer'
|
1716
|
+
it_should_behave_like 'KML_root_name'
|
1717
|
+
|
1718
|
+
it 'has the right KML' do
|
1719
|
+
Kamelopard::Wait.new
|
1720
|
+
Kamelopard::Wait.new
|
1721
|
+
Kamelopard::Wait.new
|
1722
|
+
Kamelopard::Wait.new
|
1723
|
+
|
1724
|
+
get_obj_child_content(@o, "name").should == @name
|
1725
|
+
get_obj_child_content(@o, "description").should == @description
|
1726
|
+
|
1727
|
+
playlist = get_obj_child(@o, "gx:Playlist")
|
1728
|
+
playlist.should_not be_nil
|
1729
|
+
|
1730
|
+
# There are five waits here, because Kamelopard includes one wait at
|
1731
|
+
# the beginning of each tour automatically
|
1732
|
+
playlist.children.length.should == 5
|
1733
|
+
end
|
1734
|
+
end
|
1735
|
+
|
1736
|
+
describe 'Kamelopard::ScreenOverlay' do
|
1737
|
+
before(:each) do
|
1738
|
+
@attr_name = :color
|
1739
|
+
@new_value = '11111111'
|
1740
|
+
@x = 10
|
1741
|
+
@un = :pixel
|
1742
|
+
@xy = Kamelopard::XY.new @x, @x, @un, @un
|
1743
|
+
@rotation = 10
|
1744
|
+
@name = 'some name'
|
1745
|
+
@o = Kamelopard::ScreenOverlay.new({
|
1746
|
+
:href => 'test',
|
1747
|
+
:name => @name,
|
1748
|
+
:size => @xy,
|
1749
|
+
:rotation => @rotation,
|
1750
|
+
:overlayXY => @xy,
|
1751
|
+
:screenXY => @xy,
|
1752
|
+
:rotationXY => @xy
|
1753
|
+
})
|
1754
|
+
@fields = %w[ overlayXY screenXY rotationXY size rotation ]
|
1755
|
+
end
|
1756
|
+
|
1757
|
+
it_should_behave_like 'Kamelopard::Overlay'
|
1758
|
+
it_should_behave_like 'field_producer'
|
1759
|
+
|
1760
|
+
it 'has the right KML' do
|
1761
|
+
d = @o.to_kml
|
1762
|
+
get_obj_child_content(@o, "name").should == @name
|
1763
|
+
get_obj_child_content(@o, "rotation").should == @rotation.to_s
|
1764
|
+
%w[ overlayXY screenXY rotationXY size ].each do |a|
|
1765
|
+
node = get_obj_child(@o, a)
|
1766
|
+
node.attributes['x'].should == @x.to_s
|
1767
|
+
node.attributes['y'].should == @x.to_s
|
1768
|
+
node.attributes['xunits'].should == @un.to_s
|
1769
|
+
node.attributes['yunits'].should == @un.to_s
|
1770
|
+
|
1771
|
+
end
|
1772
|
+
end
|
1773
|
+
end
|
1774
|
+
|
1775
|
+
shared_examples_for 'Kamelopard::ViewVolume' do
|
1776
|
+
before(:each) do
|
1777
|
+
@n = 53
|
1778
|
+
@fields = %w[ leftFov rightFov bottomFov topFov near ]
|
1779
|
+
end
|
1780
|
+
|
1781
|
+
it_should_behave_like 'field_producer'
|
1782
|
+
|
1783
|
+
it 'has the right KML' do
|
1784
|
+
@o.leftFov = -@n
|
1785
|
+
@o.rightFov = @n
|
1786
|
+
@o.bottomFov = -@n
|
1787
|
+
@o.topFov = @n
|
1788
|
+
@o.near = @n
|
1789
|
+
|
1790
|
+
d = @o.to_kml
|
1791
|
+
volume = get_obj_child(@o, "ViewVolume")
|
1792
|
+
match_view_vol(volume, @n)
|
1793
|
+
end
|
1794
|
+
end
|
1795
|
+
|
1796
|
+
shared_examples_for 'Kamelopard::ImagePyramid' do
|
1797
|
+
before(:each) do
|
1798
|
+
@fields = %w[ tileSize maxWidth maxHeight gridOrigin ]
|
1799
|
+
end
|
1800
|
+
|
1801
|
+
it_should_behave_like 'field_producer'
|
1802
|
+
|
1803
|
+
it 'has the right KML' do
|
1804
|
+
@o.tileSize = @n
|
1805
|
+
@o.maxWidth = @n
|
1806
|
+
@o.maxHeight = @n
|
1807
|
+
@o.gridOrigin = @n
|
1808
|
+
d = @o.to_kml
|
1809
|
+
pyramid = get_obj_child(@o, "ImagePyramid")
|
1810
|
+
match_image_pyramid(pyramid, @n)
|
1811
|
+
end
|
1812
|
+
end
|
1813
|
+
|
1814
|
+
describe 'Kamelopard::PhotoOverlay' do
|
1815
|
+
before(:each) do
|
1816
|
+
@n = 34
|
1817
|
+
@rotation = 10
|
1818
|
+
@point = Kamelopard::Point.new(@n, @n)
|
1819
|
+
@shape = 'cylinder'
|
1820
|
+
@o = Kamelopard::PhotoOverlay.new({
|
1821
|
+
:href => 'test',
|
1822
|
+
:point => @point,
|
1823
|
+
:rotation => @rotation,
|
1824
|
+
:point => @point,
|
1825
|
+
:shape => @shape,
|
1826
|
+
:leftFov => -@n,
|
1827
|
+
:rightFov => @n,
|
1828
|
+
:bottomFov => -@n,
|
1829
|
+
:topFov => @n,
|
1830
|
+
:near => @n,
|
1831
|
+
:tileSize => @n,
|
1832
|
+
:maxWidth => @n,
|
1833
|
+
:maxHeight => @n,
|
1834
|
+
:gridOrigin => @n
|
1835
|
+
})
|
1836
|
+
@fields = %w[ rotation point shape ]
|
1837
|
+
@attr_name = :color
|
1838
|
+
@new_value = '11111111'
|
1839
|
+
end
|
1840
|
+
|
1841
|
+
it_should_behave_like 'Kamelopard::Overlay'
|
1842
|
+
it_should_behave_like 'field_producer'
|
1843
|
+
it_should_behave_like 'Kamelopard::ViewVolume'
|
1844
|
+
it_should_behave_like 'Kamelopard::ImagePyramid'
|
1845
|
+
it_should_behave_like 'KML_root_name'
|
1846
|
+
|
1847
|
+
it 'has the right KML' do
|
1848
|
+
|
1849
|
+
get_obj_child_content(@o, "shape").should == @shape
|
1850
|
+
get_obj_child_content(@o, "rotation").should == @rotation.to_s
|
1851
|
+
|
1852
|
+
|
1853
|
+
volume = get_obj_child(@o, "ViewVolume")
|
1854
|
+
pyramid = get_obj_child(@o, "ImagePyramid")
|
1855
|
+
|
1856
|
+
match_view_vol(volume, @n).should be_true
|
1857
|
+
match_image_pyramid(pyramid, @n).should be_true
|
1858
|
+
end
|
1859
|
+
end
|
1860
|
+
|
1861
|
+
describe 'Kamelopard::LatLonBox' do
|
1862
|
+
before(:each) do
|
1863
|
+
@n = 130.2
|
1864
|
+
@o = Kamelopard::LatLonBox.new @n, @n, @n, @n, @n, @n, @n, :relativeToGround
|
1865
|
+
@fields = %w[ north south east west rotation minAltitude maxAltitude altitudeMode ]
|
1866
|
+
end
|
1867
|
+
|
1868
|
+
it_should_behave_like 'KML_producer'
|
1869
|
+
it_should_behave_like 'field_producer'
|
1870
|
+
|
1871
|
+
it 'has the right KML in altitude mode' do
|
1872
|
+
d = @o.to_kml(nil, true)
|
1873
|
+
get_child_content(d, "minAltitude").should == @n.to_s
|
1874
|
+
get_child_content(d, "maxAltitude").should == @n.to_s
|
1875
|
+
test_lat_lon_box(d, @o)
|
1876
|
+
end
|
1877
|
+
|
1878
|
+
it 'has the right KML in non-altitude mode' do
|
1879
|
+
d = @o.to_kml(nil, false)
|
1880
|
+
test_lat_lon_box(d, @o)
|
1881
|
+
end
|
1882
|
+
end
|
1883
|
+
|
1884
|
+
describe 'Kamelopard::LatLonQuad' do
|
1885
|
+
before(:each) do
|
1886
|
+
@n = 123.2
|
1887
|
+
@p = Kamelopard::Point.new(@n, @n)
|
1888
|
+
@o = Kamelopard::LatLonQuad.new @p, @p, @p, @p
|
1889
|
+
@fields = %w[ lowerLeft lowerRight upperRight upperLeft ]
|
1890
|
+
end
|
1891
|
+
|
1892
|
+
it_should_behave_like 'KML_producer'
|
1893
|
+
it_should_behave_like 'field_producer'
|
1894
|
+
|
1895
|
+
it 'has the right KML' do
|
1896
|
+
d = @o.to_kml
|
1897
|
+
test_lat_lon_quad(d, @n)
|
1898
|
+
end
|
1899
|
+
end
|
1900
|
+
|
1901
|
+
describe 'Kamelopard::GroundOverlay' do
|
1902
|
+
before(:each) do
|
1903
|
+
@icon_href = 'some href'
|
1904
|
+
@n = 123.2
|
1905
|
+
@lb = Kamelopard::LatLonBox.new @n, @n, @n, @n, @n, @n, @n, :relativeToGround
|
1906
|
+
@p = Kamelopard::Point.new(@n, @n)
|
1907
|
+
@lq = Kamelopard::LatLonQuad.new @p, @p, @p, @p
|
1908
|
+
@altmode = :relativeToSeaFloor
|
1909
|
+
@o = Kamelopard::GroundOverlay.new @icon_href, { :latlonbox => @lb, :latlonquad => @lq, :altitude => @n, :altitudeMode => @altmode }
|
1910
|
+
@fields = %w[ altitude altitudeMode latlonbox latlonquad ]
|
1911
|
+
@attr_name = :color
|
1912
|
+
@new_value = '11111111'
|
1913
|
+
end
|
1914
|
+
|
1915
|
+
it_should_behave_like 'Kamelopard::Overlay'
|
1916
|
+
it_should_behave_like 'field_producer'
|
1917
|
+
it_should_behave_like 'altitudeMode'
|
1918
|
+
it_should_behave_like 'KML_root_name'
|
1919
|
+
|
1920
|
+
it 'complains when latlonbox and latlonquad are nil' do
|
1921
|
+
o = Kamelopard::GroundOverlay.new @icon_href, { :altitude => @n, :altitudeMode => @altmode }
|
1922
|
+
lambda { o.to_kml }.should raise_exception
|
1923
|
+
o.latlonquad = @lq
|
1924
|
+
lambda { o.to_kml }.should_not raise_exception
|
1925
|
+
end
|
1926
|
+
|
1927
|
+
it 'has the right KML' do
|
1928
|
+
d = @o.to_kml
|
1929
|
+
get_child_content(d, 'altitude').should == @n.to_s
|
1930
|
+
|
1931
|
+
lat_lon_box = get_child d, "LatLonBox"
|
1932
|
+
test_lat_lon_box(lat_lon_box, @lb)
|
1933
|
+
|
1934
|
+
|
1935
|
+
lat_lon_quad = get_child d, "gx:LatLonQuad"
|
1936
|
+
test_lat_lon_quad(lat_lon_quad, @n)
|
1937
|
+
end
|
1938
|
+
end
|
1939
|
+
|
1940
|
+
describe 'Kamelopard::Lod' do
|
1941
|
+
before(:each) do
|
1942
|
+
@n = 324
|
1943
|
+
@o = Kamelopard::Lod.new @n, @n, @n, @n
|
1944
|
+
@fields = %w[ minpixels maxpixels minfade maxfade ]
|
1945
|
+
end
|
1946
|
+
|
1947
|
+
it_should_behave_like 'field_producer'
|
1948
|
+
it_should_behave_like 'KML_root_name'
|
1949
|
+
|
1950
|
+
it 'has the right KML' do
|
1951
|
+
d = @o.to_kml
|
1952
|
+
test_lod d, @n
|
1953
|
+
end
|
1954
|
+
end
|
1955
|
+
|
1956
|
+
describe 'Kamelopard::Region' do
|
1957
|
+
before(:each) do
|
1958
|
+
@skip_change = true
|
1959
|
+
@n = 12
|
1960
|
+
@lb = Kamelopard::LatLonBox.new @n, @n, @n, @n, @n, @n, @n, :relativeToGround
|
1961
|
+
@ld = Kamelopard::Lod.new @n, @n, @n, @n
|
1962
|
+
@o = Kamelopard::Region.new({ :latlonaltbox => @lb, :lod => @ld })
|
1963
|
+
@fields = %w[ latlonaltbox lod ]
|
1964
|
+
end
|
1965
|
+
|
1966
|
+
it_should_behave_like 'Kamelopard::Object'
|
1967
|
+
it_should_behave_like 'field_producer'
|
1968
|
+
it_should_behave_like 'KML_root_name'
|
1969
|
+
|
1970
|
+
it 'has the right KML' do
|
1971
|
+
d = @o.to_kml
|
1972
|
+
test_lat_lon_box(get_child(d, 'LatLonAltBox'), @lb)
|
1973
|
+
test_lod(get_child(d, 'Lod'), @n)
|
1974
|
+
end
|
1975
|
+
end
|
1976
|
+
|
1977
|
+
describe 'Kamelopard::Orientation' do
|
1978
|
+
before(:each) do
|
1979
|
+
@n = 37
|
1980
|
+
@o = Kamelopard::Orientation.new @n, @n, @n
|
1981
|
+
@fields = %w[ heading tilt roll ]
|
1982
|
+
end
|
1983
|
+
|
1984
|
+
it_should_behave_like 'KML_producer'
|
1985
|
+
it_should_behave_like 'field_producer'
|
1986
|
+
it_should_behave_like 'KML_root_name'
|
1987
|
+
|
1988
|
+
# it 'should complain with weird arguments' do
|
1989
|
+
# lambda { Kamelopard::Orientation.new -1, @n, @n }.should raise_exception
|
1990
|
+
# lambda { Kamelopard::Orientation.new @n, -1, @n }.should raise_exception
|
1991
|
+
# lambda { Kamelopard::Orientation.new @n, @n, -1 }.should raise_exception
|
1992
|
+
# lambda { Kamelopard::Orientation.new 483, @n, @n }.should raise_exception
|
1993
|
+
# lambda { Kamelopard::Orientation.new @n, 483, @n }.should raise_exception
|
1994
|
+
# lambda { Kamelopard::Orientation.new @n, @n, 483 }.should raise_exception
|
1995
|
+
# end
|
1996
|
+
|
1997
|
+
it 'has the right KML' do
|
1998
|
+
d = @o.to_kml
|
1999
|
+
@fields.each do |f|
|
2000
|
+
get_child_content(d, f).to_i.should == @n
|
2001
|
+
end
|
2002
|
+
end
|
2003
|
+
end
|
2004
|
+
|
2005
|
+
describe 'Kamelopard::Scale' do
|
2006
|
+
before(:each) do
|
2007
|
+
@n = 213
|
2008
|
+
@o = Kamelopard::Scale.new @n, @n, @n
|
2009
|
+
@fields = %w[ x y z ]
|
2010
|
+
end
|
2011
|
+
|
2012
|
+
it_should_behave_like 'KML_producer'
|
2013
|
+
it_should_behave_like 'field_producer'
|
2014
|
+
it_should_behave_like 'KML_root_name'
|
2015
|
+
|
2016
|
+
it 'has the right KML' do
|
2017
|
+
d = @o.to_kml
|
2018
|
+
@fields.each do |f|
|
2019
|
+
get_child_content(d, f).to_i.should == @n
|
2020
|
+
end
|
2021
|
+
end
|
2022
|
+
end
|
2023
|
+
|
2024
|
+
describe 'Kamelopard::Alias' do
|
2025
|
+
before(:each) do
|
2026
|
+
@n = 'some href'
|
2027
|
+
@o = Kamelopard::Alias.new @n, @n
|
2028
|
+
@fields = %w[ targetHref sourceHref ]
|
2029
|
+
end
|
2030
|
+
|
2031
|
+
it_should_behave_like 'KML_producer'
|
2032
|
+
it_should_behave_like 'field_producer'
|
2033
|
+
it_should_behave_like 'KML_root_name'
|
2034
|
+
|
2035
|
+
it 'has the right KML' do
|
2036
|
+
d = @o.to_kml
|
2037
|
+
@fields.each do |f|
|
2038
|
+
get_child_content(d, "#{f}").should == @n
|
2039
|
+
end
|
2040
|
+
end
|
2041
|
+
end
|
2042
|
+
|
2043
|
+
describe 'Kamelopard::ResourceMap' do
|
2044
|
+
before(:each) do
|
2045
|
+
targets = %w[ Neque porro quisquam est qui dolorem ipsum quia dolor sit amet consectetur adipisci velit ]
|
2046
|
+
sources = %w[ Lorem ipsum dolor sit amet consectetur adipiscing elit Nunc quis odio metus Fusce at ]
|
2047
|
+
@aliases = []
|
2048
|
+
targets.zip(sources).each do |a|
|
2049
|
+
@aliases << Kamelopard::Alias.new(a[0], a[1])
|
2050
|
+
end
|
2051
|
+
@o = Kamelopard::ResourceMap.new @aliases
|
2052
|
+
@fields = [ 'aliases' ]
|
2053
|
+
end
|
2054
|
+
|
2055
|
+
it_should_behave_like 'KML_producer'
|
2056
|
+
it_should_behave_like 'field_producer'
|
2057
|
+
it_should_behave_like 'KML_root_name'
|
2058
|
+
|
2059
|
+
it 'accepts various aliases correctly' do
|
2060
|
+
# ResourceMap should accept its initializer's alias argument either as
|
2061
|
+
# an array of Alias object, or as a single Alias object. The
|
2062
|
+
# before(:each) block tests the former, and this test the latter
|
2063
|
+
o = Kamelopard::ResourceMap.new Kamelopard::Alias.new('test', 'test')
|
2064
|
+
o.aliases.size.should == 1
|
2065
|
+
@o.aliases.size.should == @aliases.size
|
2066
|
+
end
|
2067
|
+
|
2068
|
+
it 'has the right KML' do
|
2069
|
+
# Make this a REXML::Document instead of just a collection of elements, for better XPath support
|
2070
|
+
doc = build_doc_from_node @o
|
2071
|
+
|
2072
|
+
@aliases.each do |a|
|
2073
|
+
find_first_kml(doc, "//kml:Alias[kml:targetHref=\"#{a.targetHref}\" and kml:sourceHref=\"#{a.sourceHref}\"]").should_not be_nil
|
2074
|
+
end
|
2075
|
+
end
|
2076
|
+
end
|
2077
|
+
|
2078
|
+
describe 'Kamelopard::Link' do
|
2079
|
+
before(:each) do
|
2080
|
+
@attr_name = :href
|
2081
|
+
@new_value = 'something else'
|
2082
|
+
@href = 'some href'
|
2083
|
+
@refreshMode = :onInterval
|
2084
|
+
@viewRefreshMode = :onRegion
|
2085
|
+
@o = Kamelopard::Link.new @href, { :refreshMode => @refreshMode, :viewRefreshMode => @viewRefreshMode }
|
2086
|
+
@fields = %w[ href refreshMode refreshInterval viewRefreshMode viewBoundScale viewFormat httpQuery ]
|
2087
|
+
end
|
2088
|
+
|
2089
|
+
it_should_behave_like 'Kamelopard::Object'
|
2090
|
+
it_should_behave_like 'KML_producer'
|
2091
|
+
it_should_behave_like 'field_producer'
|
2092
|
+
it_should_behave_like 'KML_root_name'
|
2093
|
+
|
2094
|
+
it 'has the right KML' do
|
2095
|
+
@n = 213
|
2096
|
+
@o.refreshInterval = @n
|
2097
|
+
@o.viewBoundScale = @n
|
2098
|
+
@o.viewFormat = @href
|
2099
|
+
@o.httpQuery = @href
|
2100
|
+
d = @o.to_kml
|
2101
|
+
{
|
2102
|
+
:href => @href,
|
2103
|
+
:refreshMode => @refreshMode,
|
2104
|
+
:refreshInterval => @n,
|
2105
|
+
:viewRefreshMode => @viewRefreshMode,
|
2106
|
+
:viewBoundScale => @n,
|
2107
|
+
:viewFormat => @href,
|
2108
|
+
:httpQuery => @href
|
2109
|
+
}.each do |k, v|
|
2110
|
+
get_child_content(d, k.to_s).should == v.to_s
|
2111
|
+
end
|
2112
|
+
end
|
2113
|
+
end
|
2114
|
+
|
2115
|
+
describe 'Kamelopard::Model' do
|
2116
|
+
before(:each) do
|
2117
|
+
@attr_name = :scale
|
2118
|
+
@new_value = 10
|
2119
|
+
@n = 123
|
2120
|
+
@href = 'some href'
|
2121
|
+
@refreshMode = :onInterval
|
2122
|
+
@viewRefreshMode = :onRegion
|
2123
|
+
@link = Kamelopard::Link.new @href, { :refreshMode => @refreshMode, :viewRefreshMode => @viewRefreshMode }
|
2124
|
+
@loc = Kamelopard::Point.new(@n, @n, @n)
|
2125
|
+
@orient = Kamelopard::Orientation.new @n, @n, @n
|
2126
|
+
@scale = Kamelopard::Scale.new @n, @n, @n
|
2127
|
+
targets = %w[ Neque porro quisquam est qui dolorem ipsum quia dolor sit amet consectetur adipisci velit ]
|
2128
|
+
sources = %w[ Lorem ipsum dolor sit amet consectetur adipiscing elit Nunc quis odio metus Fusce at ]
|
2129
|
+
@aliases = []
|
2130
|
+
targets.zip(sources).each do |a|
|
2131
|
+
@aliases << Kamelopard::Alias.new(a[0], a[1])
|
2132
|
+
end
|
2133
|
+
@resmap = Kamelopard::ResourceMap.new @aliases
|
2134
|
+
@o = Kamelopard::Model.new({ :link => @link, :location => @loc, :orientation => @orient, :scale => @scale, :resourceMap => @resmap })
|
2135
|
+
@fields = %w[ link location orientation scale resourceMap ]
|
2136
|
+
end
|
2137
|
+
|
2138
|
+
it_should_behave_like 'Kamelopard::Geometry'
|
2139
|
+
it_should_behave_like 'KML_producer'
|
2140
|
+
it_should_behave_like 'field_producer'
|
2141
|
+
|
2142
|
+
it 'makes the right KML' do
|
2143
|
+
d = @o.to_kml
|
2144
|
+
%w[ Link Location Orientation Scale ResourceMap ].each do |f|
|
2145
|
+
get_child(d, f).should_not be_nil
|
2146
|
+
end
|
2147
|
+
%w[ longitude latitude altitude ].each do |f|
|
2148
|
+
location = get_child(d, "Location")
|
2149
|
+
location.should_not be_nil
|
2150
|
+
get_child_content(location, f).to_i.should == @n
|
2151
|
+
end
|
2152
|
+
end
|
2153
|
+
end
|
2154
|
+
|
2155
|
+
describe 'Kamelopard::Container' do
|
2156
|
+
before(:each) do
|
2157
|
+
@o = Kamelopard::Container.new()
|
2158
|
+
end
|
2159
|
+
|
2160
|
+
it_should_behave_like 'Kamelopard::Container'
|
2161
|
+
end
|
2162
|
+
|
2163
|
+
describe 'placemark reading' do
|
2164
|
+
before(:each) do
|
2165
|
+
@s = %{<?xml version="1.0" encoding="UTF-8"?>
|
2166
|
+
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
|
2167
|
+
<Document>
|
2168
|
+
<name>My Places.kml</name>
|
2169
|
+
<Style id="some_style">
|
2170
|
+
<IconStyle>
|
2171
|
+
<scale>1.1</scale>
|
2172
|
+
<Icon>
|
2173
|
+
<href>something.png</href>
|
2174
|
+
</Icon>
|
2175
|
+
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
|
2176
|
+
</IconStyle>
|
2177
|
+
</Style>
|
2178
|
+
<Folder>
|
2179
|
+
<name>My Places</name>
|
2180
|
+
<open>1</open>
|
2181
|
+
<Placemark>
|
2182
|
+
<name>1</name>
|
2183
|
+
<LookAt>
|
2184
|
+
<longitude>-122.5701578349128</longitude>
|
2185
|
+
<latitude>37.83004301072002</latitude>
|
2186
|
+
<altitude>0</altitude>
|
2187
|
+
<heading>51.16129662831626</heading>
|
2188
|
+
<tilt>45.60413428326378</tilt>
|
2189
|
+
<range>292356.4207362059</range>
|
2190
|
+
<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
|
2191
|
+
</LookAt>
|
2192
|
+
<styleUrl>#some_style</styleUrl>
|
2193
|
+
<Point>
|
2194
|
+
<coordinates>-122.5701578349128,37.83004301072002,0</coordinates>
|
2195
|
+
</Point>
|
2196
|
+
</Placemark>
|
2197
|
+
<Placemark>
|
2198
|
+
<name>2</name>
|
2199
|
+
<LookAt>
|
2200
|
+
<longitude>-122.4831599898557</longitude>
|
2201
|
+
<latitude>37.81426712799578</latitude>
|
2202
|
+
<altitude>0</altitude>
|
2203
|
+
<heading>106.7198650112253</heading>
|
2204
|
+
<tilt>53.06224485674277</tilt>
|
2205
|
+
<range>11157.71457873637</range>
|
2206
|
+
<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
|
2207
|
+
</LookAt>
|
2208
|
+
<styleUrl>#some_style</styleUrl>
|
2209
|
+
<Point>
|
2210
|
+
<coordinates>-122.4831599898557,37.81426712799578,0</coordinates>
|
2211
|
+
</Point>
|
2212
|
+
</Placemark>
|
2213
|
+
<Placemark>
|
2214
|
+
<name>3</name>
|
2215
|
+
<LookAt>
|
2216
|
+
<longitude>-122.4791157460921</longitude>
|
2217
|
+
<latitude>37.82200644299443</latitude>
|
2218
|
+
<altitude>0</altitude>
|
2219
|
+
<heading>171.349340928465</heading>
|
2220
|
+
<tilt>52.66258054379743</tilt>
|
2221
|
+
<range>3481.461153245</range>
|
2222
|
+
<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
|
2223
|
+
</LookAt>
|
2224
|
+
<styleUrl>#some_style</styleUrl>
|
2225
|
+
<Point>
|
2226
|
+
<coordinates>-122.4791157460921,37.82200644299443,0</coordinates>
|
2227
|
+
</Point>
|
2228
|
+
</Placemark>
|
2229
|
+
</Folder>
|
2230
|
+
</Document>
|
2231
|
+
</kml>
|
2232
|
+
}
|
2233
|
+
end
|
2234
|
+
|
2235
|
+
it 'gets the right number of placemarks' do
|
2236
|
+
i = 0
|
2237
|
+
each_placemark(XML::Document.string(@s)) do |v, p|
|
2238
|
+
i += 1
|
2239
|
+
end
|
2240
|
+
i.should == 3
|
2241
|
+
end
|
2242
|
+
end
|
2243
|
+
|
2244
|
+
describe 'The band function' do
|
2245
|
+
it 'correctly calculates bands' do
|
2246
|
+
band(100, 20).should == [80, 120]
|
2247
|
+
band(100, 20).should_not == [70, 120]
|
2248
|
+
band(100, 20).should_not == [80, 140]
|
2249
|
+
end
|
2250
|
+
end
|
2251
|
+
|
2252
|
+
describe 'The latitude and longitude range checker function' do
|
2253
|
+
it 'handles longitude correctly' do
|
2254
|
+
# Within range
|
2255
|
+
long_check(35).should == 35
|
2256
|
+
# At edge of range
|
2257
|
+
long_check(180).should == 180
|
2258
|
+
# Below range
|
2259
|
+
long_check(-190).should == 170
|
2260
|
+
# Above range
|
2261
|
+
long_check(200).should == -160
|
2262
|
+
# Far below range
|
2263
|
+
long_check(-980).should == 100
|
2264
|
+
end
|
2265
|
+
|
2266
|
+
it 'handles latitude correctly' do
|
2267
|
+
# Within range
|
2268
|
+
lat_check(15).should == 15
|
2269
|
+
# At edge of range
|
2270
|
+
lat_check(90).should == 90
|
2271
|
+
# Below range
|
2272
|
+
lat_check(-95).should == 85
|
2273
|
+
# Above range
|
2274
|
+
lat_check(100).should == -80
|
2275
|
+
# Far below range
|
2276
|
+
lat_check(-980).should == -80
|
2277
|
+
end
|
2278
|
+
end
|
2279
|
+
|
2280
|
+
describe 'VSRActions' do
|
2281
|
+
before(:each) do
|
2282
|
+
@action_name = 'action name'
|
2283
|
+
@action_cmd = 'ls -1'
|
2284
|
+
@latitude = 45
|
2285
|
+
@longitude = 34
|
2286
|
+
@heading = 123
|
2287
|
+
@altitude = 453
|
2288
|
+
|
2289
|
+
@action = Kamelopard::VSRAction.new(@action_name, :constraints => {
|
2290
|
+
'latitude' => to_constraint(band(@latitude, 0.1).collect{ |v| lat_check(v) }),
|
2291
|
+
'longitude' => to_constraint(band(@longitude, 0.1).collect{ |v| long_check(v) }),
|
2292
|
+
'heading' => to_constraint(band(@heading, 1)),
|
2293
|
+
'altitude' => to_constraint(band(@altitude, 2))
|
2294
|
+
}, :action => @action_cmd)
|
2295
|
+
end
|
2296
|
+
|
2297
|
+
describe 'make themselves into hashes. A hash' do
|
2298
|
+
before(:each) do
|
2299
|
+
@hash = @action.to_hash
|
2300
|
+
end
|
2301
|
+
|
2302
|
+
it 'doesn\'t barf when created' do
|
2303
|
+
@hash.should_not be_nil
|
2304
|
+
end
|
2305
|
+
|
2306
|
+
it 'contains proper constraints' do
|
2307
|
+
@hash['constraints'].should_not be_nil
|
2308
|
+
@hash['constraints']['latitude'].should_not be_nil
|
2309
|
+
%w{latitude longitude heading altitude}.each do |i|
|
2310
|
+
@hash['constraints'][i].should =~ /\[.*, .*\]/
|
2311
|
+
end
|
2312
|
+
end
|
2313
|
+
end
|
2314
|
+
end
|
2315
|
+
|
2316
|
+
describe 'DocumentHolder' do
|
2317
|
+
it 'supports multiple documents' do
|
2318
|
+
Kamelopard::Document.new
|
2319
|
+
name_document 'First'
|
2320
|
+
i = Kamelopard::DocumentHolder.instance.document_index
|
2321
|
+
Kamelopard::Document.new
|
2322
|
+
name_document 'Second'
|
2323
|
+
j = Kamelopard::DocumentHolder.instance.document_index
|
2324
|
+
|
2325
|
+
get_doc_holder.document_index = i
|
2326
|
+
get_document.name.should == 'First'
|
2327
|
+
get_doc_holder.document_index = j
|
2328
|
+
get_document.name.should == 'Second'
|
2329
|
+
end
|
2330
|
+
|
2331
|
+
it 'can delete the current document' do
|
2332
|
+
get_folder << placemark('test')
|
2333
|
+
get_kml.find_first('//Placemark').should_not be_nil
|
2334
|
+
|
2335
|
+
dh = get_doc_holder
|
2336
|
+
dh.delete_current_doc while dh.documents.size > 0
|
2337
|
+
|
2338
|
+
get_kml.find_first('//Placemark').should be_nil
|
2339
|
+
end
|
2340
|
+
end
|
2341
|
+
|
2342
|
+
def val_within_range(o, val, expected, perc)
|
2343
|
+
res = o.run_function(val)
|
2344
|
+
res.should <= expected + perc
|
2345
|
+
res.should >= expected - perc
|
2346
|
+
end
|
2347
|
+
|
2348
|
+
shared_examples_for 'mathematical functions' do
|
2349
|
+
it 'includes the start and end points, within a margin of error' do
|
2350
|
+
val_within_range @o, @o.min, @start_value, @one_perc
|
2351
|
+
val_within_range @o, @o.max, @end_value, @one_perc
|
2352
|
+
end
|
2353
|
+
end
|
2354
|
+
|
2355
|
+
describe 'Line function' do
|
2356
|
+
before(:each) do
|
2357
|
+
@start_value = 100
|
2358
|
+
@end_value = 300
|
2359
|
+
@one_perc = (@end_value - @start_value).abs / 30.0
|
2360
|
+
@o = Kamelopard::Functions::Line.interpolate(@start_value, @end_value)
|
2361
|
+
end
|
2362
|
+
|
2363
|
+
it_should_behave_like 'mathematical functions'
|
2364
|
+
end
|
2365
|
+
|
2366
|
+
describe 'Quadratic function' do
|
2367
|
+
before(:each) do
|
2368
|
+
@start_value = 100
|
2369
|
+
@end_value = 300
|
2370
|
+
@mid_value = 20
|
2371
|
+
@one_perc = (@end_value - @mid_value).abs / 30.0
|
2372
|
+
@o = Kamelopard::Functions::Quadratic.interpolate(@start_value, @end_value, 0.5, @mid_value)
|
2373
|
+
end
|
2374
|
+
|
2375
|
+
it_should_behave_like 'mathematical functions'
|
2376
|
+
|
2377
|
+
it 'includes the midpoint' do
|
2378
|
+
val_within_range @o, 0.5, @mid_value, @one_perc
|
2379
|
+
end
|
2380
|
+
end
|
2381
|
+
|
2382
|
+
describe 'Cubic function' do
|
2383
|
+
before(:each) do
|
2384
|
+
@start_value = 70
|
2385
|
+
@end_value = 15
|
2386
|
+
@x1 = 0.3
|
2387
|
+
@y1 = 20
|
2388
|
+
@x2 = 0.6
|
2389
|
+
@y2 = 25
|
2390
|
+
@one_perc = (@end_value - @start_value).abs / 30.0
|
2391
|
+
@o = Kamelopard::Functions::Cubic.interpolate(@start_value, @end_value, @x1, @y1, @x2, @y2)
|
2392
|
+
end
|
2393
|
+
|
2394
|
+
it_should_behave_like 'mathematical functions'
|
2395
|
+
|
2396
|
+
it 'includes the defining points' do
|
2397
|
+
val_within_range @o, @x1, @y1, @one_perc
|
2398
|
+
val_within_range @o, @x2, @y2, @one_perc
|
2399
|
+
end
|
2400
|
+
end
|
2401
|
+
|
2402
|
+
describe 'make_function_path' do
|
2403
|
+
it 'handles callback_value properly' do
|
2404
|
+
i = 0
|
2405
|
+
make_function_path(10,
|
2406
|
+
:latitude => 1,
|
2407
|
+
:altitude => 1,
|
2408
|
+
:heading => 1,
|
2409
|
+
:tilt => 1,
|
2410
|
+
:roll => 0,
|
2411
|
+
:show_placemarks => 1,
|
2412
|
+
:duration => 1,
|
2413
|
+
) do |a, v|
|
2414
|
+
v[:callback_value].should == i - 1 if i > 0
|
2415
|
+
v[:callback_value] = i
|
2416
|
+
i = i + 1
|
2417
|
+
v
|
2418
|
+
end
|
2419
|
+
end
|
2420
|
+
|
2421
|
+
it 'pauses when told to' do
|
2422
|
+
clear_documents
|
2423
|
+
make_function_path( 2, :latitude => 1, :pause => 10 )
|
2424
|
+
doc = XML::Document.string(get_kml.to_s)
|
2425
|
+
doc.find("//gx:Wait/gx:duration/text()='10'", NS).should be_true
|
2426
|
+
end
|
2427
|
+
|
2428
|
+
it "handles coordinates correctly" do
|
2429
|
+
make_function_path(10, :latitude => Line.interpolate(0, 1)) do |i, h|
|
2430
|
+
h[:latitude].should == i/10.0
|
2431
|
+
h
|
2432
|
+
end
|
2433
|
+
end
|
2434
|
+
|
2435
|
+
it "handles altitudeMode and extrude correctly" do
|
2436
|
+
(v, pl) = make_function_path(10, :latitude => 10, :altitudeMode => :relativeToSeaFloor, :extrude => 1)
|
2437
|
+
pl.each do |p|
|
2438
|
+
p.geometry.extrude.should == 1
|
2439
|
+
p.altitudeMode.should == :relativeToSeaFloor
|
2440
|
+
end
|
2441
|
+
end
|
2442
|
+
|
2443
|
+
it "handles multidim correctly, and multidim overrides individual settings" do
|
2444
|
+
class TestMultiDim < Kamelopard::Functions::FunctionMultiDim
|
2445
|
+
def run_function(x)
|
2446
|
+
return [1, 1, 1, 1, 1]
|
2447
|
+
end
|
2448
|
+
end
|
2449
|
+
|
2450
|
+
a = Kamelopard.make_function_path(100,
|
2451
|
+
:altitudeMode => :relativeToGround, :tilt => 45, :show_placemarks => 1, :heading => 10,
|
2452
|
+
:multidim => [ [ TestMultiDim.new, [ :heading, :latitude, :longitude, nil, :altitude ] ] ]
|
2453
|
+
) do |i, h|
|
2454
|
+
# "multidim overrides individual settings" means that even though
|
2455
|
+
# :heading shows up as an individual constant (10), it gets its
|
2456
|
+
# final value from the multidim it's also in. Therefore, its final
|
2457
|
+
# value is 1, from the TestMultiDim class.
|
2458
|
+
[:heading, :latitude, :longitude, :altitude].each { |s| h[s].should == 1 }
|
2459
|
+
h
|
2460
|
+
end
|
2461
|
+
end
|
2462
|
+
|
2463
|
+
it "yields properly to a code block, only after other assignments are complete" do
|
2464
|
+
pt = 0
|
2465
|
+
make_function_path(5, :latitude => 10, :longitude => 10 ) do |i, h|
|
2466
|
+
i.should == pt
|
2467
|
+
pt = pt + 1
|
2468
|
+
h[:latitude].should == 10
|
2469
|
+
h[:longitude].should == 10
|
2470
|
+
h
|
2471
|
+
end
|
2472
|
+
end
|
2473
|
+
|
2474
|
+
it 'returns placemark and view arrays' do
|
2475
|
+
(v, p) = make_function_path(10, :longitude => 10)
|
2476
|
+
v.each do |view|
|
2477
|
+
view.is_a?(Kamelopard::AbstractView).should be_true
|
2478
|
+
end
|
2479
|
+
p.each do |placemark|
|
2480
|
+
placemark.is_a?(Kamelopard::Placemark).should be_true
|
2481
|
+
end
|
2482
|
+
v.size.should == 10
|
2483
|
+
p.size.should == 10
|
2484
|
+
end
|
2485
|
+
|
2486
|
+
# Sample function:
|
2487
|
+
#make_function_path(10,
|
2488
|
+
# :latitude => Line.interpolate(38.8, 40.3),
|
2489
|
+
# :altitude => Line.interpolate(10000, 2000),
|
2490
|
+
# :heading => Line.interpolate(0, 90),
|
2491
|
+
# :tilt => Line.interpolate(40.0, 90),
|
2492
|
+
# :roll => 0,
|
2493
|
+
# :show_placemarks => 1,
|
2494
|
+
# :duration => Quadratic.interpolate(2.0, 4.0, 0.0, 1.0),
|
2495
|
+
#) do |a, v|
|
2496
|
+
# puts "callback here"
|
2497
|
+
# if v.has_key? :callback_value then
|
2498
|
+
# v[:callback_value] += 1
|
2499
|
+
# else
|
2500
|
+
# v[:pause] = 0.01
|
2501
|
+
# v[:callback_value] = 1
|
2502
|
+
# end
|
2503
|
+
# puts v[:callback_value]
|
2504
|
+
# v
|
2505
|
+
#end
|
2506
|
+
|
2507
|
+
# Sample with timestamp /timespan
|
2508
|
+
# require 'time'
|
2509
|
+
# (views, placemarks) = make_function_path(10,
|
2510
|
+
# :latitude => Line.interpolate(38.8, 40.3),
|
2511
|
+
# :altitude => Line.interpolate(10000, 2000),
|
2512
|
+
# :heading => Line.interpolate(0, 90),
|
2513
|
+
# :tilt => Line.interpolate(40.0, 90),
|
2514
|
+
# :roll => 0,
|
2515
|
+
# :show_placemarks => 1,
|
2516
|
+
# :when => l,
|
2517
|
+
# :duration => Quadratic.interpolate(2.0, 4.0, 0.0, 1.0),
|
2518
|
+
# ) do |a, v|
|
2519
|
+
# tm = begintime + v[:when] * interval
|
2520
|
+
# b = tm
|
2521
|
+
# e = tm + 36000
|
2522
|
+
# b = b.xmlschema() if Kml_format
|
2523
|
+
# e = e.xmlschema() if Kml_format
|
2524
|
+
# v.delete :when
|
2525
|
+
# v[:begin] = b
|
2526
|
+
# v[:end] = e
|
2527
|
+
# if v.has_key? :callback_value then
|
2528
|
+
# v[:callback_value] += 1
|
2529
|
+
# else
|
2530
|
+
# v[:pause] = 0.01
|
2531
|
+
# v[:callback_value] = 1
|
2532
|
+
# end
|
2533
|
+
# v
|
2534
|
+
# end
|
2535
|
+
end
|
2536
|
+
|
2537
|
+
describe 'helper functions' do
|
2538
|
+
before :each do
|
2539
|
+
@view1 = make_view_from( :latitude => 1, :longitude => 1 )
|
2540
|
+
@view2 = make_view_from( :latitude => 2, :longitude => 2 )
|
2541
|
+
end
|
2542
|
+
|
2543
|
+
it 'can get_document' do
|
2544
|
+
nm = 'test document'
|
2545
|
+
name_document nm
|
2546
|
+
get_document.name.should == nm
|
2547
|
+
end
|
2548
|
+
|
2549
|
+
it 'can set flyto_mode' do
|
2550
|
+
set_flyto_mode_to :smooth
|
2551
|
+
a = fly_to @view1
|
2552
|
+
a.mode.should == :smooth
|
2553
|
+
end
|
2554
|
+
|
2555
|
+
it 'toggle_balloon_for' do
|
2556
|
+
f = get_folder
|
2557
|
+
a = placemark 'place', :description => 'place', :geometry => point(1, 1), :kml_id => 'test_placemark'
|
2558
|
+
toggle_balloon_for a, 0
|
2559
|
+
toggle_balloon_for a, 1
|
2560
|
+
d = build_doc_from_node(get_document)
|
2561
|
+
d.find("//kml:Placemark[@targetId='test_placemark']").size.should == 2
|
2562
|
+
a = point(1, 1)
|
2563
|
+
# XXX Why doesn't this catch the exception?
|
2564
|
+
#toggle_balloon_for(a, 0).should raise_exception(RuntimeError)
|
2565
|
+
end
|
2566
|
+
|
2567
|
+
# NB! Commented out on the grounds that balloons suck and we hate them.
|
2568
|
+
# it 'hide_balloon_for' do
|
2569
|
+
# pending 'Need to write this'
|
2570
|
+
# end
|
2571
|
+
#
|
2572
|
+
# it 'show_balloon_for' do
|
2573
|
+
# pending 'Need to write this'
|
2574
|
+
# end
|
2575
|
+
#
|
2576
|
+
# it 'fade_balloon_for' do
|
2577
|
+
# pending 'Need to write this'
|
2578
|
+
# end
|
2579
|
+
#
|
2580
|
+
# it 'fade_out_balloon_for' do
|
2581
|
+
# pending 'Need to write this'
|
2582
|
+
# end
|
2583
|
+
#
|
2584
|
+
# it 'fade_in_balloon_for' do
|
2585
|
+
# pending 'Need to write this'
|
2586
|
+
# end
|
2587
|
+
|
2588
|
+
it 'has working point function' do
|
2589
|
+
p = point(10, 20, 30, :relativeToGround)
|
2590
|
+
p.longitude.should == 10
|
2591
|
+
p.latitude.should == 20
|
2592
|
+
p.altitude.should == 30
|
2593
|
+
p.altitudeMode.should == :relativeToGround
|
2594
|
+
end
|
2595
|
+
|
2596
|
+
it 'has working placemark function' do
|
2597
|
+
placemark('name').class.should == Kamelopard::Placemark
|
2598
|
+
end
|
2599
|
+
|
2600
|
+
it 'get_kml' do
|
2601
|
+
get_kml.class.should == XML::Document
|
2602
|
+
end
|
2603
|
+
|
2604
|
+
it 'has working clear_documents' do
|
2605
|
+
Kamelopard::Document.new 'a'
|
2606
|
+
Kamelopard::Document.new 'b'
|
2607
|
+
Kamelopard::Document.new 'c'
|
2608
|
+
clear_documents
|
2609
|
+
get_document.name.should == ''
|
2610
|
+
end
|
2611
|
+
|
2612
|
+
it 'get_kml_string' do
|
2613
|
+
clear_documents
|
2614
|
+
name_document 'a'
|
2615
|
+
get_folder << placemark('a placemark')
|
2616
|
+
get_kml.find_first('//Document/name').should_not be_nil
|
2617
|
+
get_kml.find_first('//Placemark/name').should_not be_nil
|
2618
|
+
clear_documents
|
2619
|
+
get_kml.find_first('//Document/name').should_not be_nil
|
2620
|
+
get_kml.find_first('//Placemark/name').should be_nil
|
2621
|
+
end
|
2622
|
+
|
2623
|
+
it 'pause' do
|
2624
|
+
pause 10, :kml_id => 1
|
2625
|
+
# XXX Hack! I have no idea why I can't just get_kml.find_first, but it doesn't work
|
2626
|
+
doc = XML::Document.string(get_kml.to_s)
|
2627
|
+
doc.find_first('//gx:Wait[@id=1]', NS).should_not be_nil
|
2628
|
+
end
|
2629
|
+
|
2630
|
+
it 'get_tour' do
|
2631
|
+
get_tour.class.should == Kamelopard::Tour
|
2632
|
+
end
|
2633
|
+
|
2634
|
+
it 'name_tour' do
|
2635
|
+
name_tour 'this is a tour'
|
2636
|
+
get_tour.name.should == 'this is a tour'
|
2637
|
+
end
|
2638
|
+
|
2639
|
+
it 'get_folder' do
|
2640
|
+
get_folder.class.should == Kamelopard::Folder
|
2641
|
+
end
|
2642
|
+
|
2643
|
+
it 'folder' do
|
2644
|
+
name_folder 'test'
|
2645
|
+
folder 'test2'
|
2646
|
+
get_folder.name.should == 'test2'
|
2647
|
+
end
|
2648
|
+
|
2649
|
+
it 'name_folder' do
|
2650
|
+
name_folder 'test'
|
2651
|
+
get_folder.name.should == 'test'
|
2652
|
+
end
|
2653
|
+
|
2654
|
+
it 'name_document' do
|
2655
|
+
name_document 'a'
|
2656
|
+
get_document.name.should == 'a'
|
2657
|
+
name_document 'b'
|
2658
|
+
get_document.name.should == 'b'
|
2659
|
+
end
|
2660
|
+
|
2661
|
+
# NB! Commented out on the grounds that no one actually uses zoom_out
|
2662
|
+
# it 'zoom_out' do
|
2663
|
+
# pending 'Need to write this'
|
2664
|
+
# end
|
2665
|
+
|
2666
|
+
it 'orbit' do
|
2667
|
+
d = Document.new 'orbit test'
|
2668
|
+
p = point(10, 10)
|
2669
|
+
orbit p, 100, 90, 0, 360, { :duration => 10, :already_there => 1 }
|
2670
|
+
doc = build_doc_from_node(d)
|
2671
|
+
doc.find('//gx:FlyTo').size.should == 10
|
2672
|
+
doc.find("//gx:FlyTo/kml:LookAt/kml:heading/text()='36'").should be_true
|
2673
|
+
doc.find("//gx:FlyTo/kml:LookAt/kml:heading/text()='37'").should be_false
|
2674
|
+
doc.find("//gx:FlyTo/kml:LookAt/kml:heading/text()='72'").should be_true
|
2675
|
+
orbit p, 100, 90, 0, 360, { :duration => 10 }
|
2676
|
+
doc = build_doc_from_node(d)
|
2677
|
+
doc.find('//gx:FlyTo').size.should == 21
|
2678
|
+
end
|
2679
|
+
|
2680
|
+
# NB! Sound cues are Windoze/Mac only. So they're not too useful for our Galaxies.
|
2681
|
+
# it 'sound_cue' do
|
2682
|
+
# s = sound_cue('href')
|
2683
|
+
# s.class.should == Kamelopard::SoundCue
|
2684
|
+
# s.href.should == 'href'
|
2685
|
+
# end
|
2686
|
+
|
2687
|
+
it 'set_prefix_to' do
|
2688
|
+
old_prefix = Kamelopard.id_prefix
|
2689
|
+
set_prefix_to 'random_prefix'
|
2690
|
+
p = point(10, 10)
|
2691
|
+
p.kml_id.should =~ /random_prefix/
|
2692
|
+
set_prefix_to old_prefix
|
2693
|
+
p = point(10, 10)
|
2694
|
+
p.kml_id =~ /\d/
|
2695
|
+
end
|
2696
|
+
|
2697
|
+
it 'write_kml_to' do
|
2698
|
+
filename = 'kamelopard_test.kml.tmp'
|
2699
|
+
name_folder 'test_writing'
|
2700
|
+
write_kml_to filename
|
2701
|
+
d = XML::Document.file filename
|
2702
|
+
d.find("//kml:Folder/kml:name/text()='test_writing'").should be_true
|
2703
|
+
end
|
2704
|
+
|
2705
|
+
it 'fade_overlay' do
|
2706
|
+
o = Kamelopard::ScreenOverlay.new({
|
2707
|
+
:href => 'test',
|
2708
|
+
:name => 'something',
|
2709
|
+
:size => xy,
|
2710
|
+
:rotation => 10,
|
2711
|
+
:overlayXY => xy,
|
2712
|
+
:screenXY => xy,
|
2713
|
+
:rotationXY => xy
|
2714
|
+
})
|
2715
|
+
fade_overlay o, false, :duration => 123
|
2716
|
+
d = build_doc_from_node get_document
|
2717
|
+
d.find("//gx:AnimatedUpdate[gx:duration/text()='123' and kml:Update/kml:Change/kml:ScreenOverlay[@targetId='#{o.kml_id}']]").should be_true
|
2718
|
+
end
|
2719
|
+
|
2720
|
+
# NB! Not really worth testing this unless it gets used with any frequency at all
|
2721
|
+
# it 'TelemetryProcessor.get_heading' do
|
2722
|
+
# pending 'Need to write this'
|
2723
|
+
# end
|
2724
|
+
#
|
2725
|
+
# it 'TelemetryProcessor.get_dist2' do
|
2726
|
+
# pending 'Need to write this'
|
2727
|
+
# end
|
2728
|
+
#
|
2729
|
+
# it 'TelemetryProcessor.get_dist3' do
|
2730
|
+
# pending 'Need to write this'
|
2731
|
+
# end
|
2732
|
+
#
|
2733
|
+
# it 'TelemetryProcessor.get_tilt' do
|
2734
|
+
# pending 'Need to write this'
|
2735
|
+
# end
|
2736
|
+
#
|
2737
|
+
# it 'TelemetryProcessor.get_roll' do
|
2738
|
+
# pending 'Need to write this'
|
2739
|
+
# end
|
2740
|
+
#
|
2741
|
+
# it 'TelemetryProcessor.fix_coord' do
|
2742
|
+
# pending 'Need to write this'
|
2743
|
+
# end
|
2744
|
+
#
|
2745
|
+
# it 'TelemetryProcessor.add_flyto' do
|
2746
|
+
# pending 'Need to write this'
|
2747
|
+
# end
|
2748
|
+
#
|
2749
|
+
# it 'TelemetryProcessor.options=' do
|
2750
|
+
# pending 'Need to write this'
|
2751
|
+
# end
|
2752
|
+
#
|
2753
|
+
# it 'TelemetryProcessor.normalize_points' do
|
2754
|
+
# pending 'Need to write this'
|
2755
|
+
# end
|
2756
|
+
|
2757
|
+
it 'tour_from_points' do
|
2758
|
+
pending 'Need to write this'
|
2759
|
+
end
|
2760
|
+
|
2761
|
+
it 'make_view_from' do
|
2762
|
+
def compare(hash, view)
|
2763
|
+
fields = {
|
2764
|
+
:begin => 1, :end => 1, :when => 1
|
2765
|
+
}
|
2766
|
+
hash.each do |k, val|
|
2767
|
+
if fields.has_key? k then
|
2768
|
+
if k == :when then
|
2769
|
+
view.timestamp.when.should == val
|
2770
|
+
else
|
2771
|
+
view.timespan.method(k).call.should == val
|
2772
|
+
end
|
2773
|
+
else
|
2774
|
+
view.method(k).call.should == val
|
2775
|
+
end
|
2776
|
+
end
|
2777
|
+
end
|
2778
|
+
|
2779
|
+
hash = {
|
2780
|
+
:latitude => 10,
|
2781
|
+
:longitude => 20,
|
2782
|
+
:altitude => 30,
|
2783
|
+
:altitudeMode => :absolute,
|
2784
|
+
:heading => 40,
|
2785
|
+
:tilt => 50,
|
2786
|
+
:roll => 60,
|
2787
|
+
:begin => '2013-01-01',
|
2788
|
+
:end => '2013-02-02'
|
2789
|
+
}
|
2790
|
+
view = make_view_from hash
|
2791
|
+
view.class.should == Kamelopard::Camera
|
2792
|
+
compare(hash, view)
|
2793
|
+
|
2794
|
+
[:begin, :end, :roll].each do |k| hash.delete k end
|
2795
|
+
hash.merge!({
|
2796
|
+
:when => '2013-03-03',
|
2797
|
+
:range => 1000
|
2798
|
+
})
|
2799
|
+
view = make_view_from hash
|
2800
|
+
view.class.should == Kamelopard::LookAt
|
2801
|
+
compare(hash, view)
|
2802
|
+
end
|
2803
|
+
|
2804
|
+
it 'screenoverlay works' do
|
2805
|
+
s = screenoverlay :rotation => xy
|
2806
|
+
s.class.should == Kamelopard::ScreenOverlay
|
2807
|
+
end
|
2808
|
+
|
2809
|
+
it 'xy' do
|
2810
|
+
xy.class.should == Kamelopard::XY
|
2811
|
+
end
|
2812
|
+
|
2813
|
+
define 'handles styles' do
|
2814
|
+
before :each do
|
2815
|
+
@l = labelstyle
|
2816
|
+
@ihref = 'test'
|
2817
|
+
@i = iconstyle @ihref
|
2818
|
+
@btext = 'text'
|
2819
|
+
@b = balloonstyle @btext
|
2820
|
+
@s = style :icon => @i, :label => @l, :balloon => @b
|
2821
|
+
end
|
2822
|
+
|
2823
|
+
it 'with iconstyle' do
|
2824
|
+
@i.class.should == Kamelopard::IconStyle
|
2825
|
+
@i.href.should == @ihref
|
2826
|
+
end
|
2827
|
+
|
2828
|
+
it 'with labelstyle' do
|
2829
|
+
@l.class.should == Kamelopard::LabelStyle
|
2830
|
+
end
|
2831
|
+
|
2832
|
+
it 'with balloonstyle' do
|
2833
|
+
@b.class.should == Kamelopard::BalloonStyle
|
2834
|
+
@b.text.should == @btext
|
2835
|
+
end
|
2836
|
+
|
2837
|
+
it 'with style' do
|
2838
|
+
@s.class.should == Kamelopard::Style
|
2839
|
+
@s.icon.should == @i
|
2840
|
+
@s.balloon.should == @b
|
2841
|
+
@s.label.should == @l
|
2842
|
+
end
|
2843
|
+
end
|
2844
|
+
|
2845
|
+
it 'look_at' do
|
2846
|
+
l = look_at @view1
|
2847
|
+
l.longitude.should == @view1.longitude
|
2848
|
+
end
|
2849
|
+
|
2850
|
+
it 'camera' do
|
2851
|
+
c = camera @view1
|
2852
|
+
c.longitude.should == @view1.longitude
|
2853
|
+
end
|
2854
|
+
|
2855
|
+
it 'fly_to' do
|
2856
|
+
f = fly_to @view1, :duration => 10
|
2857
|
+
f.class.should == Kamelopard::FlyTo
|
2858
|
+
f.duration.should == 10
|
2859
|
+
end
|
2860
|
+
|
2861
|
+
it 'each_placemark works correctly' do
|
2862
|
+
kml = %[<?xml version="1.0" encoding="UTF-8"?>
|
2863
|
+
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
|
2864
|
+
<Document id="Document_3">
|
2865
|
+
<name/>
|
2866
|
+
<visibility>1</visibility>
|
2867
|
+
<open>0</open>
|
2868
|
+
<Folder id="Folder_4">
|
2869
|
+
<visibility>1</visibility>
|
2870
|
+
<open>0</open>
|
2871
|
+
<Placemark id="Placemark_2">
|
2872
|
+
<name>1</name>
|
2873
|
+
<visibility>1</visibility>
|
2874
|
+
<open>0</open>
|
2875
|
+
<Point id="Point_1">
|
2876
|
+
<coordinates>1.0, -23.0, 0</coordinates>
|
2877
|
+
<extrude>0</extrude>
|
2878
|
+
<altitudeMode>clampToGround</altitudeMode>
|
2879
|
+
</Point>
|
2880
|
+
</Placemark>
|
2881
|
+
<Placemark id="Placemark_6">
|
2882
|
+
<name>2</name>
|
2883
|
+
<visibility>1</visibility>
|
2884
|
+
<open>0</open>
|
2885
|
+
<Point id="Point_5">
|
2886
|
+
<coordinates>-164.0, -76.0, 0</coordinates>
|
2887
|
+
<extrude>0</extrude>
|
2888
|
+
<altitudeMode>clampToGround</altitudeMode>
|
2889
|
+
</Point>
|
2890
|
+
</Placemark>
|
2891
|
+
<Placemark id="Placemark_8">
|
2892
|
+
<name>3</name>
|
2893
|
+
<visibility>1</visibility>
|
2894
|
+
<open>0</open>
|
2895
|
+
<Point id="Point_7">
|
2896
|
+
<coordinates>-168.0, -18.0, 0</coordinates>
|
2897
|
+
<extrude>0</extrude>
|
2898
|
+
<altitudeMode>clampToGround</altitudeMode>
|
2899
|
+
</Point>
|
2900
|
+
</Placemark>
|
2901
|
+
</Folder>
|
2902
|
+
</Document>
|
2903
|
+
</kml>]
|
2904
|
+
placemarks = []
|
2905
|
+
each_placemark(XML::Document.string(kml)) do |p|
|
2906
|
+
placemarks << p
|
2907
|
+
end
|
2908
|
+
placemarks.size.should == 3
|
2909
|
+
end
|
2910
|
+
|
2911
|
+
it 'make_tour_index' do
|
2912
|
+
# Make sure there's some tour already
|
2913
|
+
%w[A B C].each do |i|
|
2914
|
+
Kamelopard::Tour.new "Tour #{i}"
|
2915
|
+
pause 10
|
2916
|
+
end
|
2917
|
+
make_tour_index nil, :kml_id => 'my_index'
|
2918
|
+
index_text = %{<html>
|
2919
|
+
<body>
|
2920
|
+
Something custom here.
|
2921
|
+
<ul><% @tours.each do |t| %>
|
2922
|
+
<li><a href="#<%= t.kml_id %>;flyto"></a></li>
|
2923
|
+
<% end %></ul>
|
2924
|
+
</body>
|
2925
|
+
</html>}
|
2926
|
+
make_tour_index index_text, :kml_id => 'my_index2'
|
2927
|
+
d = XML::Document.string(get_kml_string)
|
2928
|
+
['', '2'].each do |i|
|
2929
|
+
d.find("//kml:ScreenOverlay[@id='my_index#{i}']").should be_true
|
2930
|
+
end
|
2931
|
+
d.find("//kml:ScreenOverlay[@id='my_index2' and contains(description, 'Something custom here')]").should be_true
|
2932
|
+
end
|
2933
|
+
|
2934
|
+
it 'show_hide_balloon' do
|
2935
|
+
pending 'Need to write this'
|
2936
|
+
end
|
2937
|
+
|
2938
|
+
it 'cdata' do
|
2939
|
+
a = cdata 'a'
|
2940
|
+
a.cdata?.should be_true
|
2941
|
+
end
|
2942
|
+
|
2943
|
+
it 'do_action' do
|
2944
|
+
pending 'Need to write this'
|
2945
|
+
end
|
2946
|
+
|
2947
|
+
it 'great_circle_distance' do
|
2948
|
+
pending 'Need to write this'
|
2949
|
+
end
|
2950
|
+
|
2951
|
+
it 'can get the document holder' do
|
2952
|
+
get_doc_holder.class.should == Kamelopard::DocumentHolder
|
2953
|
+
end
|
2954
|
+
|
2955
|
+
it 'can bounce' do
|
2956
|
+
get_doc_holder.delete_current_doc
|
2957
|
+
get_obj_child(get_document, 'Placemark').should be_nil
|
2958
|
+
get_obj_child(get_document, 'LookAt').should be_nil
|
2959
|
+
|
2960
|
+
get_doc_holder.delete_current_doc
|
2961
|
+
bounce(@view1, @view2, 10, 10)
|
2962
|
+
get_obj_child(get_document, 'Placemark').should be_nil
|
2963
|
+
get_kml.find_first('//LookAt').should_not be_nil
|
2964
|
+
|
2965
|
+
get_doc_holder.delete_current_doc
|
2966
|
+
bounce(@view1, @view2, 10, 10, :no_flyto => 1)
|
2967
|
+
get_obj_child(get_document, 'Placemark').should be_nil
|
2968
|
+
get_kml.find_first('//LookAt').should be_nil
|
2969
|
+
|
2970
|
+
get_doc_holder.delete_current_doc
|
2971
|
+
bounce(@view1, @view2, 10, 10, :show_placemarks => 1)
|
2972
|
+
get_kml.find_first('//Placemark').should_not be_nil
|
2973
|
+
end
|
2974
|
+
end
|
2975
|
+
|
2976
|
+
describe "splines" do
|
2977
|
+
it "build and run correctly" do
|
2978
|
+
require 'kamelopard/spline'
|
2979
|
+
|
2980
|
+
sp = Kamelopard::Functions::SplineFunction.new(5)
|
2981
|
+
sp.add_control_point [4,30,30,10000,234], 10
|
2982
|
+
sp.add_control_point [8,40,30,9000,234], 30
|
2983
|
+
sp.add_control_point [8,50,50,8000,234], 100
|
2984
|
+
sp.add_control_point [4,35,50,7000,234], 10
|
2985
|
+
|
2986
|
+
spline_result = sp.run_function(0.5)
|
2987
|
+
spline_result.size.should == 5
|
2988
|
+
spline_result.should respond_to(:[])
|
2989
|
+
|
2990
|
+
# a = Kamelopard.make_function_path(100,
|
2991
|
+
# :altitudeMode => :relativeToGround, :tilt => 45, :show_placemarks => 1,
|
2992
|
+
# :multidim => [ [ sp, [ nil, :latitude, :longitude, :altitude ] ] ]
|
2993
|
+
# )
|
2994
|
+
end
|
2995
|
+
end
|
2996
|
+
|
2997
|
+
describe "viewsplines" do
|
2998
|
+
pending "Write tests for ViewSplines"
|
2999
|
+
end
|