ruby_kml 0.1.7

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.
Files changed (49) hide show
  1. data/LICENSE +7 -0
  2. data/README.md +34 -0
  3. data/Rakefile +52 -0
  4. data/examples/melbourne-stations.kml +18 -0
  5. data/lib/kml/color_style.rb +34 -0
  6. data/lib/kml/container.rb +42 -0
  7. data/lib/kml/document.rb +46 -0
  8. data/lib/kml/feature.rb +185 -0
  9. data/lib/kml/folder.rb +29 -0
  10. data/lib/kml/geometry.rb +102 -0
  11. data/lib/kml/ground_overlay.rb +18 -0
  12. data/lib/kml/hot_spot.rb +31 -0
  13. data/lib/kml/icon.rb +15 -0
  14. data/lib/kml/icon_style.rb +52 -0
  15. data/lib/kml/lat_lon_box.rb +36 -0
  16. data/lib/kml/line_string.rb +40 -0
  17. data/lib/kml/line_style.rb +15 -0
  18. data/lib/kml/linear_ring.rb +67 -0
  19. data/lib/kml/link.rb +51 -0
  20. data/lib/kml/look_at.rb +28 -0
  21. data/lib/kml/model.rb +40 -0
  22. data/lib/kml/multi_geometry.rb +26 -0
  23. data/lib/kml/object.rb +37 -0
  24. data/lib/kml/overlay.rb +21 -0
  25. data/lib/kml/placemark.rb +60 -0
  26. data/lib/kml/point.rb +65 -0
  27. data/lib/kml/poly_style.rb +16 -0
  28. data/lib/kml/polygon.rb +91 -0
  29. data/lib/kml/screen_overlay.rb +61 -0
  30. data/lib/kml/snippet.rb +25 -0
  31. data/lib/kml/style.rb +23 -0
  32. data/lib/kml/style_map.rb +39 -0
  33. data/lib/kml/style_selector.rb +7 -0
  34. data/lib/kml/version.rb +9 -0
  35. data/lib/kml_file.rb +55 -0
  36. data/lib/ruby_kml.rb +8 -0
  37. data/ruby_kml.gemspec +14 -0
  38. data/test/cdata_and_snippet.kml +21 -0
  39. data/test/ground_overlays.kml +25 -0
  40. data/test/kml/point_test.rb +10 -0
  41. data/test/kml_file_test.rb +255 -0
  42. data/test/paths.kml +33 -0
  43. data/test/polygon.kml +20 -0
  44. data/test/polygon_inner.kml +25 -0
  45. data/test/polygon_style.kml +24 -0
  46. data/test/simple_placemark.kml +12 -0
  47. data/test/style_map.kml +40 -0
  48. data/test/test_helper.rb +11 -0
  49. metadata +124 -0
@@ -0,0 +1,102 @@
1
+ module KML
2
+ class Geometry < KML::Container
3
+ # Specifies whether to connect the point to the ground. Extrusion requires that the point's +altitude_mode+ be
4
+ # either "relativeToGround" or "absolute" and that within the +coordinates+, the altitude component be greater
5
+ # than 0 (that is, in the air). Default is false.
6
+ def extrude?
7
+ @extrude
8
+ end
9
+
10
+ # Set to true to extrude.
11
+ def extrude=(v)
12
+ @extrude = v
13
+ end
14
+
15
+ # Return nil if extrude has not been defined, otherwise return '1' for true or '0' for false.
16
+ def extrude
17
+ return nil unless @extrude
18
+ @extrude ? '1' : '0'
19
+ end
20
+
21
+ # Specifies whether to allow lines and paths to follow the terrain. This specification applies only to LineStrings
22
+ # (paths) and LinearRings (polygons) that have an +altitude_mode+ of "clampToGround". Very long lines should enable
23
+ # tessellation so that they follow the curvature of the earth (otherwise, they may go underground and be hidden).
24
+ # Default is false.
25
+ def tessellate?
26
+ @tessellate
27
+ end
28
+
29
+ # Set to true to tessellate.
30
+ def tessellate=(v)
31
+ @tessellate = v
32
+ end
33
+
34
+ # Return nil if tessellate has not been defined, otherwise return '1' for true or '0' for false.
35
+ def tessellate
36
+ return nil unless @tessellate
37
+ @tessellate ? '1' : '0'
38
+ end
39
+
40
+ # Specifies how altitude components in the <coordinates> element are interpreted. Possible values are:
41
+ #
42
+ # * clampToGround - (default) Indicates to ignore an altitude specification (for example, in the +coordinates+).
43
+ # * relativeToGround - Sets the altitude of the element relative to the actual ground elevation of a particular
44
+ # location. For example, if the ground elevation of a location is exactly at sea level and the altitude for a
45
+ # point is set to 9 meters, then the elevation for the icon of a point placemark elevation is 9 meters with
46
+ # this mode. However, if the same coordinate is set over a location where the ground elevation is 10 meters
47
+ # above sea level, then the elevation of the coordinate is 19 meters. A typical use of this mode is for placing
48
+ # telephone poles or a ski lift.
49
+ # * absolute - Sets the altitude of the coordinate relative to sea level, regardless of the actual elevation
50
+ # of the terrain beneath the element. For example, if you set the altitude of a coordinate to 10 meters with
51
+ # an absolute altitude mode, the icon of a point placemark will appear to be at ground level if the terrain
52
+ # beneath is also 10 meters above sea level. If the terrain is 3 meters above sea level, the placemark will
53
+ # appear elevated above the terrain by 7 meters. A typical use of this mode is for aircraft placement.
54
+ def altitude_mode
55
+ @altitude_mode || 'clampToGround'
56
+ end
57
+
58
+ def altitude_mode_set?
59
+ !(@altitude_mode.nil?)
60
+ end
61
+
62
+ # Set the altitude mode
63
+ def altitude_mode=(mode)
64
+ allowed_modes = %w(clampToGround relativeToGround absolute)
65
+ if allowed_modes.include?(mode)
66
+ @altitude_mode = mode
67
+ else
68
+ raise ArgumentError, "Must be one of the allowed altitude modes: #{allowed_modes.join(',')}"
69
+ end
70
+ end
71
+
72
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
73
+ xm.extrude(extrude) unless extrude.nil?
74
+ xm.tessellate(tessellate) unless tessellate.nil?
75
+ xm.altitudeMode(altitude_mode) if altitude_mode_set?
76
+ end
77
+
78
+ def self.parse(node)
79
+ self.new.parse(node)
80
+ end
81
+
82
+ def parse(node)
83
+ super(node) do |cld|
84
+ case cld.name
85
+ when 'tessellate'
86
+ self.tessellate = cld.content
87
+ else
88
+ yield cld
89
+ end
90
+ end
91
+ self
92
+ end
93
+
94
+ end
95
+ end
96
+
97
+ require 'kml/point'
98
+ require 'kml/line_string'
99
+ require 'kml/linear_ring'
100
+ require 'kml/polygon'
101
+ require 'kml/model'
102
+ require 'kml/multi_geometry'
@@ -0,0 +1,18 @@
1
+ module KML #:nodoc:
2
+ # This element draws an image overlay draped onto the terrain.
3
+ class GroundOverlay < Overlay
4
+ attr_accessor :altitude
5
+ attr_accessor :altitude_mode
6
+ attr_accessor :lat_lon_box
7
+
8
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
9
+ raise InvalidKMLError, "GroundOverlay.lat_lon_box is required" if lat_lon_box.nil?
10
+ xm.GroundOverlay {
11
+ super
12
+ xm.altitude(altitude) unless altitude.nil?
13
+ xm.altitudeMode(altitude_mode) unless altitude_mode.nil?
14
+ lat_lon_box.render(xm)
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module KML #:nodoc:
2
+ # Specifies the position within the Icon that is "anchored" to the <Point> specified in the Placemark.
3
+ # The x and y values can be specified in three different ways: as pixels ("pixels"), as fractions of
4
+ # the icon ("fraction"), or as inset pixels ("insetPixels"), which is an offset in pixels from the upper
5
+ # right corner of the icon. The x and y positions can be specified in different ways—for example, x can
6
+ # be in pixels and y can be a fraction. The origin of the coordinate system is in the lower left corner
7
+ # of the icon.
8
+ #
9
+ # * x - Either the number of pixels, a fractional component of the icon, or a pixel inset indicating the
10
+ # x component of a point on the icon.
11
+ # * y - Either the number of pixels, a fractional component of the icon, or a pixel inset indicating the
12
+ # y component of a point on the icon.
13
+ # * xunits - Units in which the x value is specified. Default="fraction". A value of "fraction" indicates
14
+ # the x value is a fraction of the icon. A value of "pixels" indicates the x value in pixels. A value of
15
+ # "insetPixels" indicates the indent from the right edge of the icon.
16
+ # * yunits - Units in which the y value is specified. Default="fraction". A value of "fraction" indicates
17
+ # the y value is a fraction of the icon. A value of "pixels" indicates the y value in pixels. A value of
18
+ # "insetPixels" indicates the indent from the top edge of the icon.
19
+ class HotSpot
20
+ attr_reader :x
21
+ attr_reader :y
22
+ attr_reader :xunits
23
+ attr_reader :yunits
24
+ def initialize(x, y, xunits, yunits)
25
+ @x = x
26
+ @y = y
27
+ @xunits = xunits
28
+ @yunits = yunits
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ module KML #:nodoc:
2
+ # Defines an image associated with an Icon style or overlay. Icon has the same child elements as +Link+.
3
+ # The required href defines the location of the image to be used as the overlay or as the icon for the
4
+ # placemark. This location can either be on a local file system or a remote web server.
5
+ class Icon < Link
6
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
7
+ raise InvalidKMLError, "Icon.href must be specified" if href.nil?
8
+ xm.Icon {
9
+ self.elements.each do |a|
10
+ xm.__send__(a, self.__send__(a)) unless self.__send__(a).nil?
11
+ end
12
+ }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,52 @@
1
+ # Source file contains the code for creating the IconStyle element:
2
+ #
3
+ # <IconStyle id="ID">
4
+ # <!-- inherited from ColorStyle -->
5
+ # <color>ffffffff</color> <!-- kml:color -->
6
+ # <colorMode>normal</colorMode> <!-- kml:colorModeEnum:normal or random -->
7
+ #
8
+ # <!-- specific to IconStyle -->
9
+ # <scale>1</scale> <!-- float -->
10
+ # <heading>0</heading> <!-- float -->
11
+ # <Icon>
12
+ # <href>...</href>
13
+ # </Icon>
14
+ # <hotSpot x="0.5" y="0.5"
15
+ # xunits="fraction" yunits="fraction"/> <!-- kml:vec2Type -->
16
+ # </IconStyle>
17
+
18
+ module KML #:nodoc:
19
+ # Specifies how icons for point Placemarks are drawn, both in the Places panel and in the 3D viewer of
20
+ # Google Earth. The Icon object specifies the icon image. The +scale+ specifies the x, y scaling of the
21
+ # icon.
22
+ class IconStyle < ColorStyle
23
+ # Compass direction, in degrees. Default=0 (North). (
24
+ # <a href="http://earth.google.com/kml/kml_tags_21.html#heading">See diagram.) Values range from 0 to
25
+ # ±180 degrees.
26
+ attr_accessor :heading
27
+
28
+ # Resizes the icon (default=1).
29
+ attr_accessor :scale
30
+
31
+ # A custom Icon.
32
+ attr_accessor :icon
33
+
34
+ # Specifies the position within the Icon that is "anchored" to the Point specified in the Placemark.
35
+ # See KML::HotSpot
36
+ attr_accessor :hot_spot
37
+
38
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
39
+ xm.IconStyle {
40
+ super
41
+ xm.scale(scale) unless scale.nil?
42
+ xm.heading(heading) unless heading.nil?
43
+ icon.render(xm) unless icon.nil?
44
+ unless hot_spot.nil?
45
+ xm.hotSpot(:x => hot_spot.x, :y => hot_spot.y, :xunits => hot_spot.xunits, :yunits => hot_spot.yunits)
46
+ end
47
+ }
48
+ end
49
+ end
50
+ end
51
+
52
+ require 'kml/hot_spot'
@@ -0,0 +1,36 @@
1
+ module KML #:nodoc:
2
+ # Specifies where the top, bottom, right, and left sides of a bounding box for the ground overlay are aligned. Values for
3
+ # +north+, +south+, +east+, and +west+ are required.
4
+ #
5
+ # * +north+ (required) Specifies the latitude of the north edge of the bounding box, in decimal degrees from 0 to ±90.
6
+ # * +south+ (required) Specifies the latitude of the south edge of the bounding box, in decimal degrees from 0 to ±90.
7
+ # * +east+ (required) Specifies the longitude of the east edge of the bounding box, in decimal degrees from 0 to ±180.
8
+ # (For overlays that overlap the meridian of 180° longitude, values can extend beyond that range.)
9
+ # * +west+ (required) Specifies the longitude of the west edge of the bounding box, in decimal degrees from 0 to ±180.
10
+ # (For overlays that overlap the meridian of 180° longitude, values can extend beyond that range.)
11
+ # * +rotation+ (optional) specifies a rotation of the overlay about its center, in degrees. Values can be ±180. The
12
+ # default is 0 (north). Rotations are specified in a clockwise direction.
13
+
14
+ class LatLonBox < KML::Object
15
+ attr_accessor :north
16
+ attr_accessor :south
17
+ attr_accessor :east
18
+ attr_accessor :west
19
+ attr_accessor :rotation
20
+
21
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
22
+ raise InvalidKMLError, "LatLonBox.north is required" if north.nil?
23
+ raise InvalidKMLError, "LatLonBox.south is required" if south.nil?
24
+ raise InvalidKMLError, "LatLonBox.east is required" if east.nil?
25
+ raise InvalidKMLError, "LatLonBox.west is required" if west.nil?
26
+
27
+ xm.LatLonBox {
28
+ xm.north(north)
29
+ xm.south(south)
30
+ xm.east(east)
31
+ xm.west(west)
32
+ xm.rotation unless rotation.nil?
33
+ }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ module KML #:nodoc:
2
+ # Defines a connected set of line segments. Use LineStyle to specify the color, color mode, and width of the line.
3
+ # When a LineString is extruded, the line is extended to the ground, forming a polygon that looks somewhat like a wall.
4
+ # For extruded LineStrings, the line itself uses the current LineStyle, and the extrusion uses the current PolyStyle.
5
+ # See the <a href="http://earth.google.com/kml/kml_tut.html">KML Tutorial</a> for examples of LineStrings (or paths).
6
+ class LineString < Geometry
7
+
8
+ # Two or more coordinate tuples, each consisting of floating point values for longitude, latitude, and altitude.
9
+ # The altitude component is optional.
10
+ def coordinates
11
+ @coordinates
12
+ end
13
+
14
+ # Set the coordinates. When specifying as a String, insert a space or linebreak between tuples. Do not include spaces
15
+ # within a tuple.
16
+ def coordinates=(c)
17
+ case c
18
+ when String
19
+ @coordinates = c.strip.split(/\s+/).collect { |coord| coord.split(',') }
20
+ when Array
21
+ c.each do |coord_array|
22
+ unless coord_array.is_a?(Array)
23
+ raise ArgumentError, "If set with an array, coordinates must be specified as an array of arrays"
24
+ end
25
+ end
26
+ @coordinates = c
27
+ else
28
+ raise ArgumentError, "Coordinates must either be a String or an Array of Arrays"
29
+ end
30
+ end
31
+
32
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
33
+ raise ArgumentError, "Coordinates required" if coordinates.nil?
34
+ xm.LineString {
35
+ super
36
+ xm.coordinates(coordinates.collect { |c| c.join(',') }.join(" "))
37
+ }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,15 @@
1
+ module KML
2
+ # Specifies the drawing style (color, color mode, and line width) for all line geometry. Line geometry includes the
3
+ # outlines of outlined polygons and the extruded "tether" of Placemark icons (if extrusion is enabled).
4
+ class LineStyle < ColorStyle
5
+ # Width of the line, in pixels.
6
+ attr_accessor :width
7
+
8
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
9
+ xm.LineStyle {
10
+ super
11
+ xm.width(width) unless width.nil?
12
+ }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,67 @@
1
+ # Source code for producing a LinearRing element:
2
+ #
3
+ # <LinearRing id="ID">
4
+ # <!-- specific to LinearRing -->
5
+ # <extrude>0</extrude> <!-- boolean -->
6
+ # <tessellate>0</tessellate> <!-- boolean -->
7
+ # <altitudeMode>clampToGround</altitudeMode>
8
+ # <!-- kml:altitudeModeEnum: clampToGround, relativeToGround, or absolute -->
9
+ # <coordinates>...</coordinates> <!-- lon,lat[,alt] tuples -->
10
+ # </LinearRing>
11
+
12
+ module KML #:nodoc:
13
+ # Defines a closed line string, typically the outer boundary of a Polygon. Optionally, a LinearRing can also
14
+ # be used as the inner boundary of a Polygon to create holes in the Polygon. A Polygon can contain multiple
15
+ # LinearRing instances used as inner boundaries.
16
+ class LinearRing < Geometry
17
+ # Four or more tuples, each consisting of floating point values for longitude, latitude, and altitude.
18
+ # The altitude component is optional. Do not include spaces within a tuple. The last coordinate must be
19
+ # the same as the first coordinate. Coordinates are expressed in decimal degrees only.
20
+ def coordinates
21
+ @coordinates
22
+ end
23
+
24
+ # Set the coordinates
25
+ def coordinates=(c)
26
+ case c
27
+ when String
28
+ @coordinates = c.strip.split(/\s+/).collect { |coord| coord.split(',') }
29
+ when Array
30
+ c.each do |coord_array|
31
+ unless coord_array.is_a?(Array)
32
+ raise ArgumentError, "If set with an array, coordinates must be specified as an array of arrays"
33
+ end
34
+ end
35
+ @coordinates = c
36
+ else
37
+ raise ArgumentError, "Coordinates must either be a String or an Array of Arrays"
38
+ end
39
+ end
40
+
41
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
42
+ raise ArgumentError, "Coordinates required" if coordinates.nil?
43
+ xm.LinearRing {
44
+ super
45
+ xm.coordinates(coordinates.collect { |c| c.join(',') }.join(" "))
46
+ }
47
+ end
48
+
49
+ def self.parse(node)
50
+ self.new.parse(node)
51
+ end
52
+
53
+ def parse(node)
54
+ super(node) do |cld|
55
+ case cld.name
56
+ when 'coordinates'
57
+ self.coordinates = cld.content
58
+ else
59
+ puts "LinearRing"
60
+ p cld
61
+ puts
62
+ end
63
+ end
64
+ self
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,51 @@
1
+ module KML #:nodoc:
2
+ # Link specifies the location of any of the following:
3
+ #
4
+ # * KML files fetched by network links
5
+ # * Image files used by icons in icon styles, ground overlays, and screen overlays
6
+ # * Model files used in the Model element
7
+ #
8
+ # The file is conditionally loaded and refreshed, depending on the refresh parameters supplied here.
9
+ # Two different sets of refresh parameters can be specified: one set is based on time (+refresh_mode+ and
10
+ # +refresh_interval+) and one is based on the current "camera" view (+view_refresh_mode+ and
11
+ # +view_refresh_time+). In addition, Link specifies whether to scale the bounding box parameters that
12
+ # are sent to the server (+view_bound_scale+ and provides a set of optional viewing parameters that can
13
+ # be sent to the server (+view_format+) as well as a set of optional parameters containing version and
14
+ # language information.
15
+ #
16
+ # When a file is fetched, the URL that is sent to the server is composed of three pieces of information:
17
+ #
18
+ # * the +href+ (Hypertext Reference) that specifies the file to load.
19
+ # * an arbitrary format string that is created from (a) parameters that you specify in +view_format+ or
20
+ # (b) bounding box parameters (this is the default and is used if no +view_format+ is specified).
21
+ # * a second format string that is specified in +http_query+.
22
+ #
23
+ # If the file specified in +href+ is a local file, +view_format+ and +http_query+ are not used.
24
+ class Link < KML::Object
25
+ attr_accessor :href
26
+ attr_accessor :refresh_mode
27
+ attr_accessor :refresh_interval
28
+ attr_accessor :view_refresh_mode
29
+ attr_accessor :view_refresh_time
30
+ attr_accessor :view_bound_scale
31
+ attr_accessor :view_format
32
+ attr_accessor :http_query
33
+
34
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
35
+ raise InvalidKMLError, "Link.href must be specified" if href.nil?
36
+ xm.Link {
37
+ self.elements.each do |a|
38
+ xm.__send__(a, self.__send__(a)) unless self.__send__(a).nil?
39
+ end
40
+ }
41
+ end
42
+
43
+ protected
44
+ def elements
45
+ [
46
+ :href, :refresh_mode, :refresh_interval, :view_refresh_mode, :view_refresh_time,
47
+ :view_bound_scale, :view_format, :http_query
48
+ ]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,28 @@
1
+ # <LookAt id="ID">
2
+ # <longitude></longitude> <!-- kml:angle180 -->
3
+ # <latitude></latitude> <!-- kml:angle90 -->
4
+ # <altitude>0</altitude> <!-- double -->
5
+ # <range></range> <!-- double -->
6
+ # <tilt>0</tilt> <!-- float -->
7
+ # <heading>0</heading> <!-- float -->
8
+ # <altitudeMode>clampToGround</altitudeMode>
9
+ # <!--kml:altitudeModeEnum:clampToGround, relativeToGround, absolute -->
10
+ # </LookAt>
11
+ module KML
12
+ class LookAt < KML::Object
13
+ attr_accessor :longitude
14
+ attr_accessor :latitude
15
+ attr_accessor :altitude
16
+ attr_accessor :range
17
+ attr_accessor :tilt
18
+ attr_accessor :heading
19
+ attr_accessor :altitude_mode
20
+
21
+ def render(xm=Builder::XmlMarkup.new(:indent => 2))
22
+ [:longitude, :latitude, :altitude, :range, :tilt, :heading, :altitude_mode].each do |a|
23
+ xm.__send__(a, self.__send__(a)) unless self.__send__(a).nil?
24
+ end
25
+ end
26
+
27
+ end
28
+ end