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