kamelopard 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|