kamel 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2008 Xavier Shay
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ h1. Kamel
2
+
3
+ <pre><code>gem install kamel --source http://gems.github.com/</code></pre>
4
+
5
+ Create KML files for tasty overlays on google earth and google maps. Provides a cleaner interface than ruby_kml (which it uses internally).
6
+
7
+ Tested on ruby 1.8.6-339, 1.8.7-160 and 1.9.1-rc2
8
+
9
+ h2. Usage
10
+
11
+ <pre><code>require 'rubygems'
12
+ require 'kamel'
13
+
14
+ overlay = Kamel::Overlay.new
15
+ overlay.name = 'Melbourne Train Stations'
16
+ [
17
+ ["Flinders St", -37.818078, 144.966811],
18
+ ["Southern Cross", -37.818358, 144.952417],
19
+ ].each do |name, lat, lng|
20
+ overlay.placemark!(
21
+ :name => name,
22
+ :description => "This is a train station",
23
+ :location => {:lng => lng, :lat => lat},
24
+ :icon => "http://www.uksa.org/images/about/train-icon.gif"
25
+ )
26
+ end
27
+ puts overlay.to_kml</code></pre>
28
+
29
+ h2. Author
30
+
31
+ Xavier Shay ("http://rhnh.net":http://rhnh.net)
@@ -0,0 +1,26 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "kamel"
5
+ gemspec.summary = "Create KML files for tasty overlays on google earth and google maps"
6
+ gemspec.description = "Create KML files for tasty overlays on google earth and google maps"
7
+ gemspec.email = "contact@rhnh.net"
8
+ gemspec.homepage = "http://github.com/xaviershay/lesstile"
9
+ gemspec.authors = ["Xavier Shay"]
10
+ gemspec.test_files = Dir["spec/**/*_spec.rb"]
11
+ gemspec.add_dependency("schleyfox-ruby_kml", [">= 0.1.4"])
12
+ end
13
+ rescue LoadError
14
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
15
+ end
16
+
17
+ require 'spec/rake/spectask'
18
+
19
+ Spec::Rake::SpecTask.new do |t|
20
+ t.warning = false
21
+ t.rcov = false
22
+ t.spec_files = FileList['spec/**/*_spec.rb']
23
+ end
24
+
25
+ task :test => :spec
26
+ task :default => :spec
@@ -0,0 +1,50 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{kamel}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Xavier Shay"]
12
+ s.date = %q{2009-10-28}
13
+ s.description = %q{Create KML files for tasty overlays on google earth and google maps}
14
+ s.email = %q{contact@rhnh.net}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.textile"
18
+ ]
19
+ s.files = [
20
+ "LICENSE",
21
+ "README.textile",
22
+ "Rakefile",
23
+ "kamel.gemspec",
24
+ "lib/kamel.rb",
25
+ "lib/kamel/overlay.rb",
26
+ "spec/kamel/overlay_spec.rb",
27
+ "spec/xpath_matchers.rb"
28
+ ]
29
+ s.homepage = %q{http://github.com/xaviershay/lesstile}
30
+ s.rdoc_options = ["--charset=UTF-8"]
31
+ s.require_paths = ["lib"]
32
+ s.rubygems_version = %q{1.3.4}
33
+ s.summary = %q{Create KML files for tasty overlays on google earth and google maps}
34
+ s.test_files = [
35
+ "spec/kamel/overlay_spec.rb"
36
+ ]
37
+
38
+ if s.respond_to? :specification_version then
39
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<schleyfox-ruby_kml>, [">= 0.1.4"])
44
+ else
45
+ s.add_dependency(%q<schleyfox-ruby_kml>, [">= 0.1.4"])
46
+ end
47
+ else
48
+ s.add_dependency(%q<schleyfox-ruby_kml>, [">= 0.1.4"])
49
+ end
50
+ end
@@ -0,0 +1 @@
1
+ require 'kamel/overlay'
@@ -0,0 +1,55 @@
1
+ begin
2
+ require 'kml'
3
+ rescue LoadError
4
+ puts "You must have ruby_kml either installed to use Kamel - either as a gem or available in your path"
5
+ puts "gem install xaviershay-ruby_kml --source http://gems.github.com"
6
+ exit
7
+ end
8
+
9
+ module Kamel
10
+ class Overlay
11
+ attr_accessor :prefix
12
+ attr_accessor :name
13
+ attr_accessor :placemarks
14
+
15
+ def initialize(prefix = '')
16
+ self.prefix = prefix.to_s
17
+ self.placemarks = []
18
+ end
19
+
20
+ def placemark!(attributes)
21
+ self.placemarks << attributes
22
+ end
23
+
24
+ def to_kml
25
+ doc = KML::Document.new
26
+ doc.name = self.name unless self.name.to_s.length == 0
27
+ self.icons.each_with_index {|icon, index|
28
+ doc.styles << KML::Style.new(
29
+ :id => [prefix, 'style', index].join('-'),
30
+ :icon_style => KML::IconStyle.new(
31
+ :icon => KML::Icon.new(:href => icon)
32
+ )
33
+ )
34
+ }
35
+ self.placemarks.each do |placemark|
36
+ attrs = {}
37
+ attrs[:name] = placemark[:name].to_s unless placemark[:name].nil?
38
+ attrs[:description] = placemark[:description].to_s unless placemark[:description].nil?
39
+ attrs[:geometry] = KML::Point.new(:coordinates => placemark[:location]) unless placemark[:location].nil?
40
+ attrs[:style_url] = '#' + [prefix, 'style', self.icons.index(placemark[:icon])].join('-') unless placemark[:icon].nil?
41
+ doc.features << KML::Placemark.new(attrs)
42
+ end
43
+
44
+ kml = KMLFile.new
45
+ kml.objects << doc
46
+ kml.render
47
+ end
48
+
49
+ protected
50
+
51
+ def icons
52
+ self.placemarks.collect {|x| x[:icon]}.compact.uniq.sort
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,56 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'rubygems'
3
+ require 'spec'
4
+ require 'kamel'
5
+ require File.dirname(__FILE__) + '/../xpath_matchers'
6
+
7
+
8
+ require 'rexml/document'
9
+ require 'rexml/element'
10
+
11
+ describe Kamel::Overlay, '#to_kml' do
12
+ before(:each) do
13
+ @overlay = Kamel::Overlay.new('test')
14
+ @overlay.placemark!(:name => 'placemark-1', :location => {:lat => 1, :lng => 2}, :description => 'Place 1', :icon => 'icon-1.png')
15
+ @overlay.placemark!(:name => 'placemark-2', :location => "3,4", :description => 'Place 2', :icon => 'icon-1.png')
16
+ @overlay.placemark!(:name => 'placemark-3', :location => [5,6,7], :icon => 'icon-2.png')
17
+ @doc = @overlay.to_kml
18
+ end
19
+
20
+ it 'outputs one style block for each unique icon' do
21
+ @doc.should have_nodes("/kml/Document/Style", 2)
22
+ end
23
+
24
+ it 'outputs one placemark block for each placemark' do
25
+ @doc.should have_nodes("/kml/Document/Placemark", 3)
26
+ end
27
+
28
+ it 'records the name of each placemark' do
29
+ @doc.should match_xpath("/kml/Document/Placemark[1]/name", "placemark-1")
30
+ @doc.should match_xpath("/kml/Document/Placemark[2]/name", "placemark-2")
31
+ @doc.should match_xpath("/kml/Document/Placemark[3]/name", "placemark-3")
32
+ end
33
+
34
+ it 'records the description of each placemark if it is provided' do
35
+ #TODO Figure out how to check for CDATA
36
+ @doc.should have_xpath("/kml/Document/Placemark[1]/description")
37
+ @doc.should have_xpath("/kml/Document/Placemark[2]/description")
38
+ @doc.should_not have_xpath("/kml/Document/Placemark[3]/description")
39
+ end
40
+
41
+ it 'records the location of each placemark' do
42
+ @doc.should match_xpath("/kml/Document/Placemark[1]/Point/coordinates", "2,1")
43
+ @doc.should match_xpath("/kml/Document/Placemark[2]/Point/coordinates", "3,4")
44
+ @doc.should match_xpath("/kml/Document/Placemark[3]/Point/coordinates", "5,6,7")
45
+ end
46
+
47
+ it 'records a styleUrl that matches up to the style block for the given icon' do
48
+ doc = REXML::Document.new(@doc)
49
+ style_ids = REXML::XPath.match(doc, "/kml/Document/Style/IconStyle/Icon/href").inject({}) {|a,v|
50
+ a.update(v.text => '#' + v.parent.parent.parent.attribute('id').value)
51
+ }
52
+ @doc.should match_xpath("/kml/Document/Placemark[1]/styleUrl", style_ids['icon-1.png'])
53
+ @doc.should match_xpath("/kml/Document/Placemark[2]/styleUrl", style_ids['icon-1.png'])
54
+ @doc.should match_xpath("/kml/Document/Placemark[3]/styleUrl", style_ids['icon-2.png'])
55
+ end
56
+ end
@@ -0,0 +1,105 @@
1
+ # http://blog.wolfman.com/articles/2008/01/02/xpath-matchers-for-rspec
2
+
3
+ module Spec
4
+ module Matchers
5
+
6
+ # check if the xpath exists one or more times
7
+ class HaveXpath
8
+ def initialize(xpath)
9
+ @xpath = xpath
10
+ end
11
+
12
+ def matches?(response)
13
+ @response = response
14
+ doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response)
15
+ match = REXML::XPath.match(doc, @xpath)
16
+ not match.empty?
17
+ end
18
+
19
+ def failure_message
20
+ "Did not find expected xpath #{@xpath}"
21
+ end
22
+
23
+ def negative_failure_message
24
+ "Did find unexpected xpath #{@xpath}"
25
+ end
26
+
27
+ def description
28
+ "match the xpath expression #{@xpath}"
29
+ end
30
+ end
31
+
32
+ def have_xpath(xpath)
33
+ HaveXpath.new(xpath)
34
+ end
35
+
36
+ # check if the xpath has the specified value
37
+ # value is a string and there must be a single result to match its
38
+ # equality against
39
+ class MatchXpath
40
+ def initialize(xpath, val)
41
+ @xpath = xpath
42
+ @val= val
43
+ end
44
+
45
+ def matches?(response)
46
+ @response = response
47
+ doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response)
48
+ ok= true
49
+ REXML::XPath.each(doc, @xpath) do |e|
50
+ @actual_val= case e
51
+ when REXML::Attribute
52
+ e.to_s
53
+ when REXML::Element
54
+ e.text
55
+ else
56
+ e.to_s
57
+ end
58
+ return false unless @val == @actual_val
59
+ end
60
+ return ok
61
+ end
62
+
63
+ def failure_message
64
+ "The xpath #{@xpath} did not have the value '#{@val}'\nIt was '#{@actual_val}'"
65
+ end
66
+
67
+ def description
68
+ "match the xpath expression #{@xpath} with #{@val}"
69
+ end
70
+ end
71
+
72
+ def match_xpath(xpath, val)
73
+ MatchXpath.new(xpath, val)
74
+ end
75
+
76
+ # checks if the given xpath occurs num times
77
+ class HaveNodes #:nodoc:
78
+ def initialize(xpath, num)
79
+ @xpath= xpath
80
+ @num = num
81
+ end
82
+
83
+ def matches?(response)
84
+ @response = response
85
+ doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response)
86
+ match = REXML::XPath.match(doc, @xpath)
87
+ @num_found= match.size
88
+ @num_found == @num
89
+ end
90
+
91
+ def failure_message
92
+ "Did not find expected number of nodes #{@num} in xpath #{@xpath}\nFound #{@num_found}"
93
+ end
94
+
95
+ def description
96
+ "match the number of nodes #{@num}"
97
+ end
98
+ end
99
+
100
+ def have_nodes(xpath, num)
101
+ HaveNodes.new(xpath, num)
102
+ end
103
+
104
+ end
105
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kamel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Xavier Shay
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-28 00:00:00 +11:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: schleyfox-ruby_kml
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.1.4
24
+ version:
25
+ description: Create KML files for tasty overlays on google earth and google maps
26
+ email: contact@rhnh.net
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.textile
34
+ files:
35
+ - LICENSE
36
+ - README.textile
37
+ - Rakefile
38
+ - kamel.gemspec
39
+ - lib/kamel.rb
40
+ - lib/kamel/overlay.rb
41
+ - spec/kamel/overlay_spec.rb
42
+ - spec/xpath_matchers.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/xaviershay/lesstile
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.4
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Create KML files for tasty overlays on google earth and google maps
71
+ test_files:
72
+ - spec/kamel/overlay_spec.rb