Top Level Namespace

Defined Under Namespace

Modules: Kamelopard, TelemetryProcessor Classes: Geocoder, MapquestGeocoder, YahooGeocoder

Instance Method Summary collapse

Instance Method Details

#balloonstyle(text, options = {}) ⇒ Object

Creates an BalloonStyle object.



532
533
534
# File 'lib/kamelopard/helpers.rb', line 532

def balloonstyle(text, options = {})
    Kamelopard::BalloonStyle.new text, options
end

#band(l, p) ⇒ Object

Returns an array of two values, equal to l +/- p%, defining a “band” around the central value l NB! p is interpreted as a percentage, not a fraction. IOW the result is divided by 100.0.



608
609
610
611
# File 'lib/kamelopard/helpers.rb', line 608

def band(l, p)
    f = l * p / 100.0
    [ l - f, l + f ]
end

#bounce(a, b, duration, points, options = {}) ⇒ Object

Generates a series of points in a path that will simulate Earth’s FlyTo in bounce mode, from one view to another. Note that the view objects must be the same time: either LookAt, or Camera. Options include :no_flyto and :show_placemarks, and match make_function_path’s meanings for those options – XXX Fix the limitation that the views must be the same type XXX Make it slow down a bit toward the end of the run ++



677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
# File 'lib/kamelopard/helpers.rb', line 677

def bounce(a, b, duration, points, options = {})
    raise "Arguments to bounce() must either be Camera or LookAt objects, and must be the same type" unless
        ((a.kind_of? Kamelopard::Camera and b.kind_of? Kamelopard::Camera) or
         (a.kind_of? Kamelopard::LookAt and b.kind_of? Kamelopard::LookAt))
    # The idea here is just to generate a function; the hard bit is finding
    # control points.
    include Kamelopard
    include Kamelopard::Functions

    max_alt = a.altitude
    max_alt = b.altitude if b.altitude > max_alt

    bounce_alt = 1.3 * (b.altitude - a.altitude).abs
        # 150 is the result of trial-and-error
    gc = 0.8 * great_circle_distance(a, b) * 150
    bounce_alt = gc if gc > bounce_alt
    #raise "wtf: #{a.inspect}, #{b.inspect}"

    latlonfunc = LatLonInterp.new(a, b) do |x, y, z|
        Line.interpolate(x, y)
    end

    opts = {
        :latitude => Line.interpolate(a.latitude, b.latitude),
        :longitude => Line.interpolate(a.longitude, b.longitude),
        :multidim => [[ latlonfunc, [ :latitude, :longitude ]]],
        :heading => Line.interpolate(a.heading, b.heading),
        :tilt => Line.interpolate(a.tilt, b.tilt),
            # XXX This doesn't really work. An actual altitude requires a
            # value, and a mode, and we ignore the modes because there's no
            # way for us to figure out absolute altitudes given, say,
            # :relativeToGround
                                            # ymin,    ymax        x1         y1
        :altitude => Quadratic.interpolate(a.altitude, b.altitude, 0.5, bounce_alt),
        :altitudeMode => a.altitudeMode,
        :duration => duration * 1.0 / points,
    }
    opts[:no_flyto] = 1 if options.has_key?(:no_flyto)
    opts[:show_placemarks] = 1 if options.has_key?(:show_placemarks)

    if a.kind_of? Camera then
        opts[:roll] = Line.interpolate(a.roll, b.roll)
    else
        opts[:range] = Line.interpolate(a.range, b.range)
    end
    return make_function_path(points, opts)
end

#camera(point = nil, options = {}) ⇒ Object

Creates a Camera object focused on the given point



547
548
549
# File 'lib/kamelopard/helpers.rb', line 547

def camera(point = nil, options = {})
    Kamelopard::Camera.new point, options
end

#cdata(text) ⇒ Object

Creates a CDATA XML::Node. This is useful for, among other things, ExtendedData values



602
603
604
# File 'lib/kamelopard/helpers.rb', line 602

def cdata(text)
    XML::Node.new_cdata text.to_s
end

#circ_bounds(v, max, min) ⇒ Object

Ensures v is within the range [min, max]. Modifies v to be within that range, assuming the number line is circular (as with latitude or longitude)



616
617
618
619
620
621
622
623
624
625
626
627
628
# File 'lib/kamelopard/helpers.rb', line 616

def circ_bounds(v, max, min)
    w = max - min
    if v > max then
        while (v > max) do
            v = v - w
        end
    elsif v < min then
        while (v < min) do
            v = v + w
        end
    end
    v
end

#clear_documentsObject

Clears out the document_holder



17
18
19
20
# File 'lib/kamelopard/helpers.rb', line 17

def clear_documents
    dh = get_doc_holder
    dh.delete_current_doc while dh.documents.size > 0
end

#convert_heading(heading) ⇒ Object

Translates a heading into something between 0 and 360



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/kamelopard/helpers.rb', line 165

def convert_heading(heading)
    if heading > 360 then
        step = -360
    else
        step = 360
    end
    while heading < 0 or heading > 360 do
        heading = heading + step
    end
    heading
end

#deg2rad(a) ⇒ Object



729
730
731
# File 'lib/kamelopard/helpers.rb', line 729

def deg2rad(a)
  a * Math::PI / 180
end

#do_action(cmd, options = {}) ⇒ Object

Adds a VSRAction object (a viewsyncrelay action) to the document, for viewsyncrelay configuration



649
650
651
# File 'lib/kamelopard/helpers.rb', line 649

def do_action(cmd, options = {})
  # XXX Finish this
end

#each_placemark(d) ⇒ Object

Pulls the Placemarks from the KML document d and yields each in turn to the caller d = an XML::Document containing KML XXX This currently expects Placemarks to contain LookAt or Camera objects. It should do something useful with placemarks based on Points, or other objects



559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
# File 'lib/kamelopard/helpers.rb', line 559

def each_placemark(d)
    d.find('//kml:Placemark').each do |p|
        all_values = {}

        # These fields are part of the abstractview
        view_fields = %w{ latitude longitude heading range tilt roll altitude altitudeMode gx:altitudeMode }
        # These are other field I'm interested in
        other_fields = %w{ description name }
        all_fields = view_fields.clone
        all_fields.concat(other_fields.clone)
        all_fields.each do |k|
            if k == 'gx:altitudeMode' then
                ix = k
                next unless p.find_first('kml:altitudeMode').nil?
            else
                ix = "kml:#{k}"
            end
            r = k == "gx:altitudeMode" ? :altitudeMode : k.to_sym 
            tmp = p.find_first("descendant::#{ix}")
            next if tmp.nil?
            all_values[k == "gx:altitudeMode" ? :altitudeMode : k.to_sym ] = tmp.content
        end
        view_values = {}
        view_fields.each do |v| view_values[v.to_sym] = all_values[v.to_sym].clone if all_values.has_key? v.to_sym end
        yield make_view_from(view_values), all_values
    end
end

#fade_balloon_for(obj, value, options = {}) ⇒ Object

Fades a placemark’s popup balloon in or out. Takes as arguments the placemark object, 0 or 1 to hide or show the balloon, respectively, and a has of options to be passed to the AnimatedUpdate object created by this function. In order to have the balloon fade over some noticeable time, at minimum the :duration attribute in this hash should be set to some meaningful number of seconds.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/kamelopard/helpers.rb', line 70

def fade_balloon_for(obj, value, options = {})
    au = Kamelopard::AnimatedUpdate.new [], options
    if ! obj.is_a? Kamelopard::Placemark then
        raise "Can't show balloons for things that aren't placemarks"
    end
    a = XML::Node.new 'Change'
    b = XML::Node.new 'Placemark'
    b.attributes['targetId'] = obj.kml_id
    c = XML::Node.new 'color'
    c << XML::Node.new_text(value.to_s)
    b << c
    a << b
    au << a
end

#fade_in_balloon_for(p, options = {}) ⇒ Object

Refer to fade_balloon_for. This function only fades the balloon in.



91
92
93
# File 'lib/kamelopard/helpers.rb', line 91

def fade_in_balloon_for(p, options = {})
    fade_balloon_for(p, 'ffffffff', options)
end

#fade_out_balloon_for(obj, options = {}) ⇒ Object

Refer to fade_balloon_for. This function only fades the balloon out.



86
87
88
# File 'lib/kamelopard/helpers.rb', line 86

def fade_out_balloon_for(obj, options = {})
    fade_balloon_for(obj, '00ffffff', options)
end

#fade_overlay(ov, show, options = {}) ⇒ Object

Fades a screen overlay in or out. The show argument is boolean; true to show the overlay, or false to hide it. The fade will happen smoothly (as opposed to immediately) if the options hash includes a :duration element set to some positive number of seconds.



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/kamelopard/helpers.rb', line 295

def fade_overlay(ov, show, options = {})
    color = '00ffffff'
    color = 'ffffffff' if show
    if ov.is_a? String then
        id = ov  
    else
        id = ov.kml_id
    end

    a = XML::Node.new 'Change'
    b = XML::Node.new 'ScreenOverlay'
    b.attributes['targetId'] = id
    c = XML::Node.new 'color'
    c << XML::Node.new_text(color)
    b << c
    a << b
    k = Kamelopard::AnimatedUpdate.new [a], options 
end

#fly_to(view = nil, options = {}) ⇒ Object

Creates a FlyTo object flying to the given AbstractView



552
553
554
# File 'lib/kamelopard/helpers.rb', line 552

def fly_to(view = nil, options = {})
    Kamelopard::FlyTo.new view, options
end

#folder(name) ⇒ Object

Creates a new Folder with the current name



141
142
143
# File 'lib/kamelopard/helpers.rb', line 141

def folder(name)
    Kamelopard::Folder.new(name)
end

#get_actionsObject

Returns the Document’s VSRActions as a YAML string, suitable for writing to a viewsyncrelay configuration file



655
656
657
# File 'lib/kamelopard/helpers.rb', line 655

def get_actions
  get_document.get_actions_yaml
end

#get_doc_holderObject



664
665
666
# File 'lib/kamelopard/helpers.rb', line 664

def get_doc_holder
  return Kamelopard::DocumentHolder.instance
end

#get_documentObject

Returns the current Document object



7
8
9
# File 'lib/kamelopard/helpers.rb', line 7

def get_document()
    Kamelopard::DocumentHolder.instance.current_document
end

#get_folderObject

Returns the current Folder object



134
135
136
137
138
# File 'lib/kamelopard/helpers.rb', line 134

def get_folder()
    f = Kamelopard::DocumentHolder.instance.current_document.folders.last
    Kamelopard::Folder.new() if f.nil?
    Kamelopard::DocumentHolder.instance.current_document.folders.last
end

#get_kmlObject

Returns the KML that makes up the current Kamelopard::Document



109
110
111
# File 'lib/kamelopard/helpers.rb', line 109

def get_kml
    Kamelopard::DocumentHolder.instance.current_document.get_kml_document
end

#get_kml_stringObject

Returns the KML that makes up the current Document, as a string



114
115
116
# File 'lib/kamelopard/helpers.rb', line 114

def get_kml_string
    get_kml.to_s
end

#get_tourObject

Returns the current Tour object



124
125
126
# File 'lib/kamelopard/helpers.rb', line 124

def get_tour()
    Kamelopard::DocumentHolder.instance.current_document.tour
end

#great_circle_distance(a, b) ⇒ Object

Returns the great circle distance between two points



726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
# File 'lib/kamelopard/helpers.rb', line 726

def great_circle_distance(a, b)
    # Stolen from http://rosettacode.org/wiki/Haversine_formula#Ruby

    def deg2rad(a)
      a * Math::PI / 180
    end

    radius = 6371  # rough radius of the Earth, in kilometers
    lat1, long1 = [Math::PI * a.latitude / 180.0, Math::PI * a.longitude / 180.0]
    lat2, long2 = [Math::PI * b.latitude / 180.0, Math::PI * b.longitude / 180.0]
    d = 2 * radius * 
        Math.asin( Math.sqrt(
            Math.sin((lat2-lat1)/2)**2 +
            Math.cos(lat1) * Math.cos(lat2) *
            Math.sin((long2 - long1)/2)**2
        ))
   
    return d
end

#hide_balloon_for(obj, options = {}) ⇒ Object

Hides the popup balloon for a Placemark or ScreenOverlay object. Require the object as the first argument, and takes a hash of options passed to the AnimatedUpdate object this functino creates. See also show_balloon_for and toggle_balloon_for



52
53
54
# File 'lib/kamelopard/helpers.rb', line 52

def hide_balloon_for(obj, options = {})
    toggle_balloon_for(obj, 0, options)
end

#iconstyle(href = nil, options = {}) ⇒ Object

Creates an IconStyle object.



522
523
524
# File 'lib/kamelopard/helpers.rb', line 522

def iconstyle(href = nil, options = {})
    Kamelopard::IconStyle.new href, options
end

#labelstyle(scale = 1, options = {}) ⇒ Object

Creates an LabelStyle object.



527
528
529
# File 'lib/kamelopard/helpers.rb', line 527

def labelstyle(scale = 1, options = {})
    Kamelopard::LabelStyle.new scale, options
end

#lat_check(l) ⇒ Object

These functions ensure the given value is within appropriate bounds for a latitude or longitude. Modifies it as necessary if it’s not.



632
633
634
# File 'lib/kamelopard/helpers.rb', line 632

def lat_check(l)
    circ_bounds(l * 1.0, 90.0, -90.0)
end

#long_check(l) ⇒ Object

See lat_check()



637
638
639
# File 'lib/kamelopard/helpers.rb', line 637

def long_check(l)
    circ_bounds(l * 1.0, 180.0, -180.0)
end

#look_at(point = nil, options = {}) ⇒ Object

Creates a LookAt object focused on the given point



542
543
544
# File 'lib/kamelopard/helpers.rb', line 542

def look_at(point = nil, options = {})
    Kamelopard::LookAt.new point, options
end

#make_tour_index(erb = nil, options = {}) ⇒ Object

Makes an HTML tour index, linked to a one-pixel screen overlay. The HTML contains links to start each tour.



589
590
591
# File 'lib/kamelopard/helpers.rb', line 589

def make_tour_index(erb = nil, options = {})
    get_document.make_tour_index(erb, options)
end

#make_view_from(options = {}) ⇒ Object

Given a hash of values, this creates an AbstractView object. Possible values in the hash are :latitude, :longitude, :altitude, :altitudeMode, :tilt, :heading, :roll, :range, :begin, :end, and :when. If the hash specifies :roll, a Camera object will result; otherwise, a LookAt object will result. Specifying both :roll and :range will still result in a Camera object, and the :range option will be ignored.

:begin, :end, and :when are used to create the view’s timestamp or timespan

:roll, :range, and the timestamp / timespan options have no default; all other values default to 0 except :altitudeMode, which defaults to :relativeToGround.



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/kamelopard/helpers.rb', line 466

def make_view_from(options = {})
    o = {}
    o.merge! options
    options.each do |k, v|
        o[k.to_sym] = v unless k.kind_of? Symbol
    end

    # Set defaults
    [
        [ :altitude, 0 ],
        [ :altitudeMode, :relativeToGround ],
        [ :latitude, 0 ],
        [ :longitude, 0 ],
        [ :tilt, 0 ],
        [ :heading, 0 ],
        [ :extrude, 0 ],
    ].each do |a|
        o[a[0]] = a[1] unless o.has_key? a[0]
    end

    p = point o[:longitude], o[:latitude], o[:altitude], o[:altitudeMode], o[:extrude]

    if o.has_key? :roll then
        view = Kamelopard::Camera.new p
    else
        view = Kamelopard::LookAt.new p
    end

    if o.has_key? :when then
        o[:timestamp] = Kamelopard::TimeStamp.new(o[:when])
    elsif o.has_key? :begin or o.has_key? :end then
        (b, e) = [nil, nil]
        b = o[:begin] if o.has_key? :begin
        e = o[:end] if o.has_key? :end
        o[:timespan] = Kamelopard::TimeSpan.new(b, e)
    end

    [ :altitudeMode, :tilt, :heading, :timespan, :timestamp, :range, :roll, :viewerOptions ].each do |a|
        #p o[a] if o.has_key? a and a == :timestamp
        view.method("#{a.to_s}=").call(o[a]) if o.has_key? a
    end

    view
end

#name_document(name) ⇒ Object

Names (or renames) the current Document object, and returns it



152
153
154
155
# File 'lib/kamelopard/helpers.rb', line 152

def name_document(name)
    Kamelopard::DocumentHolder.instance.current_document.name = name
    return Kamelopard::DocumentHolder.instance.current_document
end

#name_folder(name) ⇒ Object

Names (or renames) the current Folder, and returns it



146
147
148
149
# File 'lib/kamelopard/helpers.rb', line 146

def name_folder(name)
    Kamelopard::DocumentHolder.instance.current_document.folder.name = name
    return Kamelopard::DocumentHolder.instance.current_document.folder
end

#name_tour(name) ⇒ Object

Sets a name for the current Tour



129
130
131
# File 'lib/kamelopard/helpers.rb', line 129

def name_tour(name)
    Kamelopard::DocumentHolder.instance.current_document.tour.name = name
end

#orbit(center, range = 100, tilt = 90, startHeading = 0, endHeading = 360, options = {}) ⇒ Object

Creates a list of FlyTo elements to orbit and look at a given point (center), at a given range (in meters), starting and ending at given angles (in degrees) from the center, where 0 and 360 (and -360, and 720, and -980, etc.) are north. To orbit multiple times, add or subtract 360 from the endHeading. The tilt argument matches the KML LookAt tilt argument already_there, if true, means we’ve already flown to the initial point The options hash can contain:

:duration   The total duration of the orbit. Defaults to 0, which means it will take 2 seconds per step
:step       How much to change the heading for each flyto. Defaults to some strange value >= 5
:already_there
            Default false. Indicates that we've already flown to the initial position


189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/kamelopard/helpers.rb', line 189

def orbit(center, range = 100, tilt = 90, startHeading = 0, endHeading = 360, options = {})
    duration = options.has_key?(:duration) ? options[:duration] : 0
    step = options.has_key?(:step) ? options[:step] : nil
    already_there = options.has_key?(:already_there) ? options[:already_there] : false

    am = center.altitudeMode
  
    if not step.nil? then
        if (endHeading - startHeading > 0 and step < 0) or (endHeading - startHeading < 0 and step > 0) then
            raise "Given start = #{startHeading}, end = #{endHeading}, and step = #{step}, this will be an infinite loop"
        end
    end

    # We want at least 5 points (arbitrarily chosen value), plus at least 5 for
    # each full revolution

    # When I tried this all in one step, ruby told me 360 / 10 = 1805. I'm sure
    # there's some reason why this is a feature and not a bug, but I'd rather
    # not look it up right now.
    dur = 2
    if step.nil? then
      num = (endHeading - startHeading).abs
      num_steps = ((endHeading - startHeading) / 360.0).to_i.abs * 5 + 5
      step = num / num_steps
      step = 1 if step < 1
      step = step * -1 if startHeading > endHeading
      if already_there
         num_steps = num_steps - 1
         startHeading = startHeading + step
      end
      if duration != 0
        dur = duration.to_f / num_steps
      end
    else
      dur = duration * 1.0 / ((endHeading - startHeading) * 1.0 / step) if duration != 0
      startHeading = startHeading + step if already_there
    end

    lastval = startHeading
    mode = :bounce
    mode = :smooth if already_there
    startHeading.step(endHeading, step) do |theta|
        lastval = theta
        heading = convert_heading theta
        fly_to Kamelopard::LookAt.new(center, :heading => heading, :tilt => tilt, :range => range, :altitudeMode => am), :duration => dur, :mode => mode
        mode = :smooth
    end
    if lastval != endHeading then
        fly_to Kamelopard::LookAt.new(center, :heading => convert_heading(endHeading), :tilt => tilt, :range => range, :altitudeMode => am), :duration => dur, :mode => :smooth
    end
end

#pause(p, options = {}) ⇒ Object

Inserts a KML gx:Wait element



119
120
121
# File 'lib/kamelopard/helpers.rb', line 119

def pause(p, options = {})
    Kamelopard::Wait.new p, options
end

#placemark(name = nil, options = {}) ⇒ Object

Creates a Placemark with the given name. Other Placemark attributes are set in the options hash.



104
105
106
# File 'lib/kamelopard/helpers.rb', line 104

def placemark(name = nil, options = {})
    Kamelopard::Placemark.new name, options
end

#point(lo, la, alt = 0, mode = nil, extrude = false) ⇒ Object

Creates a Point object. Arguments are latitude, longitude, altitude, altitude mode, and extrude



97
98
99
100
# File 'lib/kamelopard/helpers.rb', line 97

def point(lo, la, alt=0, mode=nil, extrude = false)
    m = ( mode.nil? ? :clampToGround : mode )
    Kamelopard::Point.new(lo, la, alt, :altitudeMode => m, :extrude => extrude)
end

#screenoverlay(options = {}) ⇒ Object

Creates a ScreenOverlay object



512
513
514
# File 'lib/kamelopard/helpers.rb', line 512

def screenoverlay(options = {})
    Kamelopard::ScreenOverlay.new options
end

#set_flyto_mode_to(mode) ⇒ Object

Changes the default FlyTo mode. Possible values are :smooth and :bounce



12
13
14
# File 'lib/kamelopard/helpers.rb', line 12

def set_flyto_mode_to(mode)
    Kamelopard::DocumentHolder.instance.current_document.flyto_mode = mode
end

#set_prefix_to(a) ⇒ Object

Sets a prefix for all kml_id objects. Note that this does not change previously created objects’ kml_ids… just new kml_ids going forward.



273
274
275
# File 'lib/kamelopard/helpers.rb', line 273

def set_prefix_to(a)
    Kamelopard.id_prefix = a
end

#show_balloon_for(obj, options = {}) ⇒ Object

Displays the popup balloon for a Placemark or ScreenOverlay object. Require the object as the first argument, and takes a hash of options passed to the AnimatedUpdate object this functino creates. See also show_balloon_for and toggle_balloon_for



60
61
62
# File 'lib/kamelopard/helpers.rb', line 60

def show_balloon_for(obj, options = {})
    toggle_balloon_for(obj, 1, options)
end

#show_hide_balloon(p, wait, options = {}) ⇒ Object

Superceded by toggle_balloon_for, but retained for backward compatibility



594
595
596
597
598
# File 'lib/kamelopard/helpers.rb', line 594

def show_hide_balloon(p, wait, options = {})
    show_balloon_for p, options
    pause wait
    hide_balloon_for p, options
end

#sound_cue(href, ds = nil) ⇒ Object

Adds a SoundCue object.



242
243
244
# File 'lib/kamelopard/helpers.rb', line 242

def sound_cue(href, ds = nil)
    Kamelopard::SoundCue.new href, ds
end

#style(options = {}) ⇒ Object

Creates an Style object.



537
538
539
# File 'lib/kamelopard/helpers.rb', line 537

def style(options = {})
    Kamelopard::Style.new options
end

#to_constraint(arr) ⇒ Object

Turns an array of two values (min, max) into a string suitable for use as a viewsyncrelay constraint



643
644
645
# File 'lib/kamelopard/helpers.rb', line 643

def to_constraint(arr)
  "[#{arr[0]}, #{arr[1]}]"
end

#toggle_balloon_for(obj, value, options = {}) ⇒ Object

Shows or hides the popup balloon for Placemark and ScreenOverlay objects. Arguments are the object; 0 or 1 to hide or show the balloon, respectively; and a hash of options to be added to the AnimatedUpdate object this function creates. Refer to the AnimatedUpdate documentation for details on possible options.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/kamelopard/helpers.rb', line 28

def toggle_balloon_for(obj, value, options = {})
    au = Kamelopard::AnimatedUpdate.new [], options
    if ! obj.kind_of? Kamelopard::Placemark and ! obj.kind_of? Kamelopard::ScreenOverlay then
        raise "Can't show balloons for things that aren't Placemarks or ScreenOverlays"
    end
    a = XML::Node.new 'Change'
    # XXX This can probably be more robust, based on just the class's name
    if obj.kind_of? Kamelopard::Placemark then
        b = XML::Node.new 'Placemark'
    else
        b = XML::Node.new 'ScreenOverlay'
    end
    b.attributes['targetId'] = obj.kml_id
    c = XML::Node.new 'gx:balloonVisibility'
    c << XML::Node.new_text(value.to_s)
    b << c
    a << b
    au << a
end

#tour_from_points(points, options = {}) ⇒ Object

Creates a tour from a series of points, using TelemetryProcessor::add_flyto.

The first argument is an ordered array of points, where each point is represented as an array of longitude, latitude, and altitude (in meters), in that order. The only options currently recognized are :pause and :exaggerate. :pause controls the flight speed by specifying the duration of each FlyTo element. Its default is 1 second. There is currently no mechanism for having anything other than constant durations between points. :exaggerate is an numeric value that defaults to 1; when set to larger values, it will exaggerate tilt and roll values, because they’re sort of boring at normal scale.



443
444
445
446
447
448
449
450
451
452
# File 'lib/kamelopard/helpers.rb', line 443

def tour_from_points(points, options = {})
    options.merge!({
        :pause => 1,
        :exaggerate => 1
    }) { |key, old, new| old }
    TelemetryProcessor.options = options
    (0..(points.size-3)).each do |i|
        TelemetryProcessor::add_flyto points[i,3]
    end
end

#write_actions_to(filename = 'actions.yml') ⇒ Object

Writes actions to a viewsyncrelay config file



660
661
662
# File 'lib/kamelopard/helpers.rb', line 660

def write_actions_to(filename = 'actions.yml')
  File.open(filename, 'w') do |f| f.write get_actions end
end

#write_kml_to(file = 'doc.kml', actions_file = 'actions.yml') ⇒ Object

Writes KML output (and if applicable, viewsyncrelay configuration) to files. Include a file name for the actions_file argument to get viewsyncrelay configuration output as well. Note that this configuration includes only the actions section; users are responsible for creating appropriate linkages, inputs and outputs, and transformations, on their own, presumably in a separate file.



283
284
285
286
287
288
289
# File 'lib/kamelopard/helpers.rb', line 283

def write_kml_to(file = 'doc.kml', actions_file = 'actions.yml')
    File.open(file, 'w') do |f| f.write get_kml.to_s end
    if (get_document.vsr_actions.size > 0) then
        File.open(actions_file, 'w') do |f| f.write get_document.get_actions end
    end
    #File.open(file, 'w') do |f| f.write get_kml.to_s.gsub(/balloonVis/, 'gx:balloonVis') end
end

#xy(x = 0.5, y = 0.5, xt = :fraction, yt = :fraction) ⇒ Object

Creates an XY object, for use when building Overlay objects



517
518
519
# File 'lib/kamelopard/helpers.rb', line 517

def xy(x = 0.5, y = 0.5, xt = :fraction, yt = :fraction)
    Kamelopard::XY.new x, y, xt, yt
end

#zoom_out(dist = 1000, dur = 0, mode = nil) ⇒ Object



157
158
159
160
161
162
# File 'lib/kamelopard/helpers.rb', line 157

def zoom_out(dist = 1000, dur = 0, mode = nil)
    l = Kamelopard::DocumentHolder.instance.current_document.tour.last_abs_view
    raise "No current position to zoom out from\n" if l.nil?
    l.range += dist
    Kamelopard::FlyTo.new(l, nil, dur, mode)
end