kamelopard 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/kamelopard/classes.rb +155 -29
- data/lib/kamelopard/functions.rb +589 -418
- metadata +7 -5
data/lib/kamelopard/classes.rb
CHANGED
@@ -11,12 +11,13 @@ module Kamelopard
|
|
11
11
|
require 'xml'
|
12
12
|
require 'yaml'
|
13
13
|
require 'erb'
|
14
|
+
require 'cgi'
|
14
15
|
|
15
16
|
@@sequence = 0
|
16
17
|
@@id_prefix = ''
|
17
18
|
|
18
19
|
def Kamelopard.get_document
|
19
|
-
|
20
|
+
DocumentHolder.instance.current_document
|
20
21
|
end
|
21
22
|
|
22
23
|
def Kamelopard.get_next_id # :nodoc
|
@@ -127,6 +128,11 @@ module Kamelopard
|
|
127
128
|
attr_accessor :kml_id
|
128
129
|
attr_reader :comment
|
129
130
|
|
131
|
+
# This constructor looks for values in the options hash that match
|
132
|
+
# class attributes, and sets those attributes to the values in the
|
133
|
+
# hash. So a class with an attribute called :when can be set via the
|
134
|
+
# constructor by including ":when => some-value" in the options
|
135
|
+
# argument to the constructor.
|
130
136
|
def initialize(options = {})
|
131
137
|
@kml_id = "#{Kamelopard.id_prefix}#{self.class.name.gsub('Kamelopard::', '')}_#{ Kamelopard.get_next_id }"
|
132
138
|
|
@@ -140,15 +146,15 @@ module Kamelopard
|
|
140
146
|
end
|
141
147
|
end
|
142
148
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
end
|
149
|
+
# Adds an XML comment to this node. Handles HTML escaping the comment
|
150
|
+
# if needed
|
151
|
+
def comment=(cmnt)
|
152
|
+
require 'cgi'
|
153
|
+
@comment = CGI.escapeHTML(cmnt)
|
149
154
|
end
|
150
155
|
|
151
|
-
# Returns
|
156
|
+
# Returns XML::Node containing this object's KML. Objects should
|
157
|
+
# override this method
|
152
158
|
def to_kml(elem)
|
153
159
|
elem.attributes['id'] = @kml_id.to_s
|
154
160
|
if not @comment.nil? and @comment != '' then
|
@@ -260,9 +266,9 @@ module Kamelopard
|
|
260
266
|
# Note that this will not accept a one-dimensional array of numbers to add
|
261
267
|
# a single point. Instead, create a Point with those numbers, and pass
|
262
268
|
# it to add_element
|
263
|
-
|
269
|
+
#--
|
264
270
|
# XXX The above stipulation is a weakness that needs fixing
|
265
|
-
|
271
|
+
#++
|
266
272
|
def add_element(a)
|
267
273
|
if a.kind_of? Enumerable then
|
268
274
|
# We've got some sort of array or list. It could be a list of
|
@@ -517,7 +523,9 @@ module Kamelopard
|
|
517
523
|
class TimePrimitive < Object
|
518
524
|
end
|
519
525
|
|
520
|
-
# Corresponds to KML's TimeStamp object. The @when attribute must be in a
|
526
|
+
# Corresponds to KML's TimeStamp object. The @when attribute must be in a
|
527
|
+
# format KML understands. Refer to the KML documentation to see which
|
528
|
+
# formats are available.
|
521
529
|
class TimeStamp < TimePrimitive
|
522
530
|
attr_accessor :when
|
523
531
|
def initialize(ts_when = nil, options = {})
|
@@ -605,7 +613,7 @@ module Kamelopard
|
|
605
613
|
end
|
606
614
|
end
|
607
615
|
|
608
|
-
# ExtendedData SchemaData objects
|
616
|
+
# Corresponds to KML's ExtendedData SchemaData objects
|
609
617
|
class SchemaData
|
610
618
|
attr_accessor :schemaUrl, :simpleData
|
611
619
|
def initialize(schemaUrl, simpleData = {})
|
@@ -632,13 +640,14 @@ module Kamelopard
|
|
632
640
|
end
|
633
641
|
|
634
642
|
# Abstract class corresponding to KML's Feature object.
|
643
|
+
#--
|
635
644
|
# XXX Make this support alternate namespaces
|
645
|
+
#++
|
636
646
|
class Feature < Object
|
637
|
-
# Abstract class
|
638
647
|
attr_accessor :visibility, :open, :atom_author, :atom_link, :name,
|
639
|
-
:phoneNumber, :
|
640
|
-
:
|
641
|
-
attr_reader :addressDetails, :snippet, :extendedData
|
648
|
+
:phoneNumber, :abstractView, :styles, :timeprimitive, :styleUrl,
|
649
|
+
:styleSelector, :region, :metadata
|
650
|
+
attr_reader :addressDetails, :snippet, :extendedData, :description
|
642
651
|
|
643
652
|
include Snippet
|
644
653
|
|
@@ -650,6 +659,15 @@ module Kamelopard
|
|
650
659
|
@name = name unless name.nil?
|
651
660
|
end
|
652
661
|
|
662
|
+
def description=(a)
|
663
|
+
b = CGI.escapeHTML(a)
|
664
|
+
if b != a then
|
665
|
+
@description = XML::Node.new_cdata a
|
666
|
+
else
|
667
|
+
@description = a
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
653
671
|
def extendedData=(a)
|
654
672
|
raise "extendedData attribute must respond to the 'each' method" unless a.respond_to? :each
|
655
673
|
@extendedData = a
|
@@ -695,9 +713,9 @@ module Kamelopard
|
|
695
713
|
|
696
714
|
def addressDetails=(a)
|
697
715
|
if a.nil? or a == '' then
|
698
|
-
|
716
|
+
DocumentHolder.instance.current_document.uses_xal = false
|
699
717
|
else
|
700
|
-
|
718
|
+
DocumentHolder.instance.current_document.uses_xal = true
|
701
719
|
end
|
702
720
|
@addressDetails = a
|
703
721
|
end
|
@@ -794,7 +812,7 @@ module Kamelopard
|
|
794
812
|
@styles = []
|
795
813
|
@folders = []
|
796
814
|
super
|
797
|
-
|
815
|
+
DocumentHolder.instance.current_document.folders << self
|
798
816
|
end
|
799
817
|
|
800
818
|
def styles=(a)
|
@@ -844,18 +862,29 @@ module Kamelopard
|
|
844
862
|
k
|
845
863
|
end
|
846
864
|
|
847
|
-
# Represents KML's Document class.
|
848
|
-
# scripts can (for now) manage only one Document at a time.
|
865
|
+
# Represents KML's Document class.
|
849
866
|
class Document < Container
|
850
|
-
|
851
|
-
attr_accessor :flyto_mode, :folders, :tours, :uses_xal
|
867
|
+
attr_accessor :flyto_mode, :folders, :tours, :uses_xal, :vsr_actions
|
852
868
|
|
853
869
|
def initialize(options = {})
|
854
870
|
@tours = []
|
855
871
|
@folders = []
|
872
|
+
@vsr_actions = []
|
873
|
+
DocumentHolder.instance << self
|
856
874
|
super
|
857
875
|
end
|
858
876
|
|
877
|
+
# Returns viewsyncrelay actions as a hash
|
878
|
+
def get_actions
|
879
|
+
{
|
880
|
+
'actions' => @vsr_actions.collect { |a| a.to_hash }
|
881
|
+
}
|
882
|
+
end
|
883
|
+
|
884
|
+
def get_actions_yaml
|
885
|
+
get_actions.to_yaml
|
886
|
+
end
|
887
|
+
|
859
888
|
# Returns the current Tour object
|
860
889
|
def tour
|
861
890
|
Tour.new if @tours.length == 0
|
@@ -955,6 +984,61 @@ module Kamelopard
|
|
955
984
|
end
|
956
985
|
end
|
957
986
|
|
987
|
+
# Holds a set of Document objects, so we can work with multiple KML files
|
988
|
+
# at once and keep track of them. It's important for Kamelopard's usability
|
989
|
+
# to have the concept of a "current" document, so we don't have to specify
|
990
|
+
# the document we're talking about each time we do something interesting.
|
991
|
+
# This class supports that idea.
|
992
|
+
class DocumentHolder
|
993
|
+
include Singleton
|
994
|
+
attr_accessor :document_index, :initialized
|
995
|
+
attr_reader :documents
|
996
|
+
|
997
|
+
def initialize(doc = nil)
|
998
|
+
@documents = []
|
999
|
+
@document_index = -1
|
1000
|
+
if ! doc.nil?
|
1001
|
+
self.documents << doc
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
def document_index
|
1006
|
+
return @document_index
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
def document_index=(a)
|
1010
|
+
@document_index = a
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
def current_document
|
1014
|
+
# Automatically create a Document if we don't already have one
|
1015
|
+
if @documents.size <= 0
|
1016
|
+
Document.new
|
1017
|
+
@document_index = 0
|
1018
|
+
end
|
1019
|
+
return @documents[@document_index]
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
def <<(a)
|
1023
|
+
raise "Cannot add a non-Document object to a DocumentHolder" unless a.kind_of? Document
|
1024
|
+
@documents << a
|
1025
|
+
@document_index += 1
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
def [](a)
|
1029
|
+
return @documents[a]
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
def []=(i, v)
|
1033
|
+
raise "Cannot include a non-Document object in a DocumentHolder" unless v.kind_of? Document
|
1034
|
+
@documents[i] = v
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def size
|
1038
|
+
return @documents.size
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
|
958
1042
|
# Corresponds to KML's ColorStyle object. Color is stored as an 8-character hex
|
959
1043
|
# string, with two characters each of alpha, blue, green, and red values, in
|
960
1044
|
# that order, matching the ordering the KML spec demands.
|
@@ -1273,7 +1357,7 @@ module Kamelopard
|
|
1273
1357
|
def initialize(options = {})
|
1274
1358
|
super
|
1275
1359
|
@attached = false
|
1276
|
-
|
1360
|
+
DocumentHolder.instance.current_document.styles << self
|
1277
1361
|
end
|
1278
1362
|
|
1279
1363
|
def attached?
|
@@ -1411,7 +1495,7 @@ module Kamelopard
|
|
1411
1495
|
attr_accessor :standalone
|
1412
1496
|
|
1413
1497
|
def initialize(options = {})
|
1414
|
-
|
1498
|
+
DocumentHolder.instance.current_document.tour << self unless options[:standalone]
|
1415
1499
|
super
|
1416
1500
|
end
|
1417
1501
|
end
|
@@ -1585,12 +1669,13 @@ module Kamelopard
|
|
1585
1669
|
class Tour < Object
|
1586
1670
|
attr_accessor :name, :description, :last_abs_view, :playlist, :icon
|
1587
1671
|
|
1588
|
-
def initialize(name = nil, description = nil)
|
1672
|
+
def initialize(name = nil, description = nil, no_wait = false)
|
1589
1673
|
super()
|
1590
1674
|
@name = name
|
1591
1675
|
@description = description
|
1592
1676
|
@playlist = []
|
1593
|
-
|
1677
|
+
DocumentHolder.instance.current_document.tours << self
|
1678
|
+
Wait.new(0.1, :comment => "This wait is automatic, and helps prevent animation glitches") unless no_wait
|
1594
1679
|
end
|
1595
1680
|
|
1596
1681
|
# Add another element to this Tour
|
@@ -1622,7 +1707,7 @@ module Kamelopard
|
|
1622
1707
|
|
1623
1708
|
def initialize(options = {})
|
1624
1709
|
super nil, options
|
1625
|
-
|
1710
|
+
DocumentHolder.instance.current_document.folder << self
|
1626
1711
|
end
|
1627
1712
|
|
1628
1713
|
def to_kml(elem)
|
@@ -1799,7 +1884,7 @@ module Kamelopard
|
|
1799
1884
|
Kamelopard.add_altitudeMode(@altitudeMode, k)
|
1800
1885
|
end
|
1801
1886
|
m = XML::Node.new 'rotation'
|
1802
|
-
m
|
1887
|
+
m << @rotation.to_s
|
1803
1888
|
k << m
|
1804
1889
|
elem << k unless elem.nil?
|
1805
1890
|
k
|
@@ -2113,6 +2198,7 @@ module Kamelopard
|
|
2113
2198
|
end
|
2114
2199
|
end
|
2115
2200
|
|
2201
|
+
# Abstract class corresponding to KML's MultiGeometry object
|
2116
2202
|
class MultiGeometry < Geometry
|
2117
2203
|
attr_accessor :geometries
|
2118
2204
|
|
@@ -2136,6 +2222,7 @@ module Kamelopard
|
|
2136
2222
|
end
|
2137
2223
|
end
|
2138
2224
|
|
2225
|
+
# Analogue of KML's NetworkLink class
|
2139
2226
|
class NetworkLink < Feature
|
2140
2227
|
attr_accessor :refreshVisibility, :flyToView, :link
|
2141
2228
|
|
@@ -2185,6 +2272,7 @@ module Kamelopard
|
|
2185
2272
|
end
|
2186
2273
|
end
|
2187
2274
|
|
2275
|
+
# Corresponds to Google Earth's gx:Track extension to KML
|
2188
2276
|
class Track < Geometry
|
2189
2277
|
attr_accessor :altitudeMode, :when, :coord, :angles, :model
|
2190
2278
|
def initialize(options = {})
|
@@ -2210,5 +2298,43 @@ module Kamelopard
|
|
2210
2298
|
e
|
2211
2299
|
end
|
2212
2300
|
end
|
2301
|
+
|
2302
|
+
# Viewsyncrelay action
|
2303
|
+
class VSRAction < Object
|
2304
|
+
attr_accessor :name, :tour_name, :verbose, :fail_count, :input,
|
2305
|
+
:action, :exit_action, :repeat, :constraints, :reset_constraints,
|
2306
|
+
:initially_disabled
|
2307
|
+
# XXX Consider adding some constraints, so that things like @name and @action don't go nil
|
2308
|
+
# XXX Also ensure constraints and reset_constraints are hashes,
|
2309
|
+
# containing reasonable values, and reasonable keys ('latitude' vs.
|
2310
|
+
# :latitude, for instance)
|
2311
|
+
|
2312
|
+
def initialize(name, options = {})
|
2313
|
+
@name = name
|
2314
|
+
@constraints = {}
|
2315
|
+
@repeat = 'DEFAULT'
|
2316
|
+
@input = 'ALL'
|
2317
|
+
super(options)
|
2318
|
+
|
2319
|
+
DocumentHolder.instance.current_document.vsr_actions << self
|
2320
|
+
end
|
2321
|
+
|
2322
|
+
def to_hash
|
2323
|
+
a = {}
|
2324
|
+
a['name'] = @name unless @name.nil?
|
2325
|
+
a['id'] = @id unless @id.nil?
|
2326
|
+
a['input'] = @input unless @input.nil?
|
2327
|
+
a['tour_name'] = @tour_name unless @tour_name.nil?
|
2328
|
+
a['verbose'] = @verbose unless @verbose.nil?
|
2329
|
+
a['fail_count'] = @fail_count unless @fail_count.nil?
|
2330
|
+
a['action'] = @action unless @action.nil?
|
2331
|
+
a['exit_action'] = @exit_action unless @exit_action.nil?
|
2332
|
+
a['repeat'] = @repeat unless @repeat.nil?
|
2333
|
+
a['initially_disabled'] = @initially_disabled unless @initially_disabled.nil?
|
2334
|
+
a['constraints'] = @constraints unless @constraints.nil?
|
2335
|
+
a['reset_constraints'] = @reset_constraints unless @reset_constraints.nil?
|
2336
|
+
a
|
2337
|
+
end
|
2338
|
+
end
|
2213
2339
|
end
|
2214
2340
|
# End of Kamelopard module
|