Module: Kamelopard

Defined in:
lib/kamelopard/spline.rb,
lib/kamelopard/classes.rb,
lib/kamelopard/function.rb,
lib/kamelopard/multicam.rb,
lib/kamelopard/function_paths.rb

Overview

– ++

Defined Under Namespace

Modules: CoordinateList, Functions, Icon, ImagePyramid, Multicam, Snippet, ViewVolume Classes: AbstractView, Alias, AnimatedUpdate, BalloonStyle, Camera, ColorStyle, Container, Data, Document, DocumentHolder, Feature, FlyTo, Folder, Geometry, GroundOverlay, IconStyle, LabelStyle, LatLonBox, LatLonQuad, LineString, LineStyle, LinearRing, Link, ListStyle, Lod, LookAt, Model, MultiGeometry, NetworkLink, Object, Orientation, Overlay, PhotoOverlay, Placemark, Point, PolyStyle, Polygon, Region, ResourceMap, Scale, SchemaData, ScreenOverlay, SoundCue, Style, StyleMap, StyleSelector, TimePrimitive, TimeSpan, TimeStamp, Tour, TourControl, TourPrimitive, Track, VSRAction, Wait, XY

Constant Summary collapse

LogLevels =

Valid log levels:

  • :debug

  • :info

  • :notice

  • :warn

  • :error

  • :fatal

{
    :debug => 0,
    :info => 1,
    :notice => 2,
    :warn => 3,
    :error => 4,
    :fatal => 5
}
@@sequence =
0
@@id_prefix =
''
@@logger =
nil
@@log_level =
LogLevels[:notice]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.add_altitudeMode(mode, e) ⇒ Object

Helper function for altitudeMode / gx:altitudeMode elements



155
156
157
158
159
160
161
162
163
164
# File 'lib/kamelopard/classes.rb', line 155

def Kamelopard.add_altitudeMode(mode, e) # :nodoc:
    return if mode.nil?
    if mode == :clampToGround or mode == :relativeToGround or mode == :absolute then
        t = XML::Node.new 'altitudeMode'
    else
        t = XML::Node.new 'gx:altitudeMode'
    end
    t << mode.to_s
    e << t
end

.convert_coord(a) ⇒ Object

– Accepts XdX’X.X“, XDXmX.XXs, XdXmX.XXs, or X.XXXX with either /- or N/E/S/W +



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/kamelopard/classes.rb', line 108

def Kamelopard.convert_coord(a)    # :nodoc:
    a = a.to_s.upcase.strip.gsub(/\s+/, '')

    if a =~ /^[+-]?\d+(\.\d+)?$/ then
        # coord needs no transformation
        return a.to_f
    elsif a =~ /^[+-]?\d+\.\d+E?-?\d+/ then
        # Scientific notation
        return a.to_f
    end

    mult = 1
    if a =~ /^-/ then
        mult *= -1
    end
    a = a.sub /^\+|-/, ''
    a = a.strip

    if a =~ /[SW]$/ then
        mult *= -1
    end
    a = a.sub /[NESW]$/, ''
    a = a.strip

    if a =~ /^\d+D\d+M\d+(\.\d+)?S$/ then
        # coord is in dms
        p = a.split /[D"']/
        a = p[0].to_f + (p[2].to_f / 60.0 + p[1].to_f) / 60.0
    elsif a =~ /^\d+D\d+'\d+(\.\d+)?"$/ then
        # coord is in d'"
        p = a.split /[D"']/
        a = p[0].to_f + (p[2].to_f / 60.0 + p[1].to_f) / 60.0
    elsif m = (a =~ /^(\d+)°(\d+)'(\d+\.\d+)?"$/) then
        # coord is in °'"
        b = a
        a = $1.to_f + ($3.to_f / 60.0 + $2.to_f) / 60.0
    else
        raise "Couldn't determine coordinate format for #{a}"
    end

    # check that it's within range
    a = a.to_f * mult
    raise "Coordinate #{a} out of range" if a > 180 or a < -180
    return a.to_f
end

.get_next_idObject

:nodoc:



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

def Kamelopard.get_next_id   # :nodoc:
    @@sequence += 1
    @@sequence
end

.id_prefixObject

Returns the current kml_id prefix value. See #Kamelopard.id_prefix=



72
73
74
# File 'lib/kamelopard/classes.rb', line 72

def Kamelopard.id_prefix
    @@id_prefix
end

.id_prefix=(a) ⇒ Object

Sets a prefix for all kml_id values generated from this time forth. Does not change previously generated kml_ids



67
68
69
# File 'lib/kamelopard/classes.rb', line 67

def Kamelopard.id_prefix=(a)
    @@id_prefix = a
end

.kml_array(e, m) ⇒ Object

– Intelligently adds elements to a KML object. Expects the KML object as the first argument, an array as the second. Each entry in the array is itself an array, containing first an Object, and second either a string or a Proc object. If the first Object is nil, nothing happens. If it’s not nil, then:

* if the second element is a string, add a new element to the KML. This
  string is the element name, and the stringified form of the first element
  is its text value
* if the second element is a proc, call the proc, passing it the KML
  object, and let the Proc (presumably) add itself to the KML

++



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/kamelopard/classes.rb', line 87

def Kamelopard.kml_array(e, m) # :nodoc:
    m.map do |a|
        if ! a[0].nil? then
            if a[1].kind_of? Proc then
                a[1].call(e)
            elsif a[0].kind_of? XML::Node then
                d = XML::Node.new(a[1])
                d << a[0]
                e << d
            else
                t = XML::Node.new a[1]
                t << a[0].to_s
                e << t
            end
        end
    end
end

.log(level, mod, msg) ⇒ Object

Logs a message, provided a log level, a text string, and the log message. See #Kamelopard.set_logger for details.



55
56
57
58
# File 'lib/kamelopard/classes.rb', line 55

def Kamelopard.log(level, mod, msg)
    raise "Unknown log level #{level} for error message #{msg}" unless LogLevels.has_key? level
    @@logger.call(level, mod, msg) unless @@logger.nil? or @@log_level > LogLevels[level]
end

.set_log_level(lev) ⇒ Object

Sets the current logging level. Valid levels are defined in the LogLevels hash



48
49
50
51
# File 'lib/kamelopard/classes.rb', line 48

def Kamelopard.set_log_level(lev)
    raise "Unknown log level #{lev}" unless LogLevels.has_key? lev
    @@log_level = LogLevels[lev]
end

.set_logger(l) ⇒ Object

Sets a logging callback function. This function should expect three arguments. The first will be a log level (:debug, :info, :notice, :warn, :error, or :fatal); the second will be a text string, categorizing the log entries generally; and the third will be the log message itself



43
44
45
# File 'lib/kamelopard/classes.rb', line 43

def Kamelopard.set_logger(l)
    @@logger = l
end

Instance Method Details

#get_stack_traceObject

:nodoc:



991
992
993
994
995
# File 'lib/kamelopard/classes.rb', line 991

def get_stack_trace   # :nodoc:
    k = ''
    caller.each do |a| k << "#{a}\n" end
    k
end

#make_function_path(points = 10, options = {}) ⇒ Object

This function creates a hash, then uses that hash to create a point in a tour, using make_view_from() among other things. Arguments:

points: The number of points in the series
hash: Values used to create the hash, which creates the point in the
series. Keys in this hash include:
  Any option suitable for the make_view_from() function
    These can be constant numbers, Proc objects, or Function1D objects.
    The latter two will be called once for each point in the series.
    Proc objects will be passed the number of the point they're
    calculating, starting with 0, and the current value of the hash
    created for this point. "duration" represents the time in seconds
    spent flying from the last point to this one.
  callback
    This Proc object, if defined, will be called after the other hash
    keys have been calculated. It gets passed the number of the point,
    and the current value of the hash for this point. It can modify and
    return that hash as needed.
  callback_value
    A placeholder the callback function can use. It can set it when
    it's called one time, and see that value when called the next time.
  pause
    The amount of time to pause after flying to this point, or nil for no pause
  show_placemarks
    If set, a placemark object will be created at this point
  no_flyto
    If set, on flyto objects will be created
  multidim
    An array. Each array element is itself an array, containing two
    values. The first is associated with a FunctionMultiDim class
    representing a multidimensional function. The second is an array of
    symbols and nils. Valid symbols include any of the possible
    make_function_path options, except :multidim. At execution, the
    FunctionMultiDim will be evaluated, returning an array of values.
    The symbols in the :vals array will be assigned the returned value
    corresponding to their position in the :vals array. For instance,
    assume the following :multidim argument
       [ [ myFunc, [:latitude, :longitude, nil, :altitude] ],
         [ anotherFunc, [:pause] ] ]
    When myFunc is evaluated, assume it returns [1, 2, 3, 4, 5]. Thus,
    :latitude will be 1, :longitude 2, and so on. Because :vals[2] is
    nil, the corresponding element in the results of myFunc will be
    ignored. Also, given that :vals contains four values whereas myFunc
    returned 5, the unallocated final myFunc value will also be
    ignored.
 NOTE ON PROCESSING ORDER
    Individually specified hash options are processed first, followed by
    :multidim. So hash options included directly as
    well as in a :multidim :vals array will take the value from
    :multidim. make_function_path yields to code blocks last, after all
    other assignment.


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/kamelopard/function_paths.rb', line 61

def make_function_path(points = 10, options = {})

    def val(a, b, c) # :nodoc:
        if a.kind_of? Function then
            return a.get_value(c)
        elsif a.kind_of? Proc then
            return a.call(b, a)
        else
            return a
        end
    end

    views = []
    placemarks = []

    callback_value = nil
    i = 0
    while (i <= points)
        p = i.to_f / points.to_f
        hash = {}
        [ :latitude, :longitude, :altitude, :heading,
          :tilt, :altitudeMode, :extrude, :when,
          :roll, :range, :pause, :begin, :end, :show_placemarks,
          :no_flyto, :pause
        ].each do |k|
            if options.has_key? k then
                hash[k] = val(options[k], i, p)
            end
        end

        hash[:show_placemarks] = options[:show_placemarks] if options.has_key? :show_placemarks
        #hash[:roll] = val(options[:roll], i, p) if options.has_key? :roll
        #hash[:range] = val(options[:range], i, p) if options.has_key? :range
        #hash[:pause] = val(options[:pause], i, p) if options.has_key? :pause

        if options.has_key? :duration
            duration = val(options[:duration], i, p)
        else
            duration = (i == 0 ? 0 : 2)
        end
        hash[:duration] = duration

        if options.has_key? :multidim then
            options[:multidim].each do |md|
                r = val(md[0], i, p)
                md[1].each_index do |ind|
                    hash[md[1][ind]] = r[ind] unless md[1][ind].nil?
                end
            end
        end

        hash[:callback_value] = callback_value unless callback_value.nil?

        begin
            tmp = yield(i, hash)
            hash = tmp unless tmp.nil?
        rescue LocalJumpError
            # Don't do anything; there's no block to yield to
        end
        #hash = options[:callback].call(i, hash) if options.has_key? :callback
        callback_value = hash[:callback_value] if hash.has_key? :callback_value

        v = make_view_from(hash)
        p = point(v.longitude, v.latitude, v.altitude, hash[:altitudeMode], hash[:extrude])
        # XXX Should I add the view's timestamp / timespan, if it exists, to the placemark?
        pl = placemark(i.to_s, :geometry => p)
        pl.abstractView = v
        get_folder << pl if hash.has_key? :show_placemarks
        fly_to v, :duration => duration , :mode => :smooth unless hash.has_key? :no_flyto
        views << v
        placemarks << pl

        pause hash[:pause] if hash.has_key? :pause

        i = i + 1
    end
    [views, placemarks]
end

#val(a, b, c) ⇒ Object

:nodoc:



63
64
65
66
67
68
69
70
71
# File 'lib/kamelopard/function_paths.rb', line 63

def val(a, b, c) # :nodoc:
    if a.kind_of? Function then
        return a.get_value(c)
    elsif a.kind_of? Proc then
        return a.call(b, a)
    else
        return a
    end
end