amanzi-sld 0.0.1

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.
@@ -0,0 +1,152 @@
1
+ #/usr/bin/env ruby
2
+
3
+ module Amanzi
4
+ module XML
5
+ class Element
6
+ attr_reader :name, :children, :depth
7
+ attr_accessor :attributes, :namespace
8
+ def initialize(name,depth=0)
9
+ @name = name
10
+ @depth = depth
11
+ @children = []
12
+ @attributes = {}
13
+ end
14
+ # Utility for setting the namepace in a method-chaining DSL
15
+ def ns(ns)
16
+ self.namespace = ns
17
+ self
18
+ end
19
+ def []= (key,value)
20
+ @attributes[key] = value
21
+ end
22
+ def insert index, child
23
+ @children.insert index, child
24
+ end
25
+ def << child
26
+ @children << child
27
+ end
28
+ def make_child(name,options={},&block)
29
+ child = Element.new(name,depth+1)
30
+ namespace && (child.namespace = namespace)
31
+ options.each{|k,v| child[k]=v}
32
+ block && block.call(child)
33
+ child
34
+ end
35
+ def insert_child(index,name,options={},&block)
36
+ insert index, child = make_child(name,options,&block)
37
+ child
38
+ end
39
+ def add_child(name,options={},&block)
40
+ self << child = make_child(name,options,&block)
41
+ child
42
+ end
43
+ def comment(text)
44
+ @children << Comment.new(text)
45
+ end
46
+ def self.camelize(symbol)
47
+ symbol.to_s.gsub(/__/,':_').gsub(/(^|_)(\w)/){"#{$2.upcase}"}.gsub(/^(\w+):/){"#{$1.downcase}:"}
48
+ end
49
+ def method_missing(symbol,*args,&block)
50
+ add_child(Element.camelize(symbol), *args, &block)
51
+ end
52
+ def indent(offset=0)
53
+ @indent ||= []
54
+ @indent[offset] ||= (0...(depth+offset)).inject(''){|a,v|a << (@xml_options[:tab] || "\t")}
55
+ end
56
+ def attribute_text
57
+ attributes.empty? ? "" : " #{attributes.to_a.map{|x|"#{x[0]}=\"#{x[1]}\""}.join(' ')}"
58
+ end
59
+ def contents
60
+ children.length==1 && !children[0].is_a?(Element) && children[0].to_s ||
61
+ "\n#{indent(1)}#{children.map{|x|x.to_xml(@xml_options)}.join("\n#{indent(1)}")}\n#{indent}"
62
+ end
63
+ def tag
64
+ namespace ? "#{namespace}:#{name}" : name
65
+ end
66
+ def to_xml(options={})
67
+ @xml_options = options
68
+ children.empty? ? "<#{tag}#{attribute_text}/>" : "<#{tag}#{attribute_text}>#{contents}</#{tag}>"
69
+ end
70
+ def to_s
71
+ tag
72
+ end
73
+ end
74
+ class Comment < Element
75
+ def to_xml(options={})
76
+ "<!-- #{[name,children].flatten.map{|c| c.to_s}.join(', ')} -->"
77
+ end
78
+ end
79
+
80
+ class Document < Element
81
+ def to_xml(options={})
82
+ "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" + super(options) + "\n"
83
+ end
84
+ def singleton_elements
85
+ @singleton_elements ||= []
86
+ end
87
+ def comment text
88
+ !@singleton_elements.empty? && @singleton_elements.flatten[-1].comment(text)
89
+ end
90
+ def add_singleton_elements(elements=[])
91
+ prev_e = nil
92
+ singleton_elements << elements.map do |e|
93
+ parent = prev_e || self
94
+ element = Element.new(Element.camelize(e), parent.depth + 1)
95
+ parent << element
96
+ prev_e = element
97
+ end
98
+ end
99
+ def singleton_method(symbol,*args,&block)
100
+ name = Element.camelize symbol
101
+ singleton_elements.flatten.each do |element|
102
+ if element.name === name
103
+ #puts "Found singleton: #{name}"
104
+ block && block.call(element)
105
+ return element
106
+ end
107
+ end
108
+ #puts "Found no singletons for #{name}"
109
+ nil
110
+ end
111
+ def method_missing(symbol,*args,&block)
112
+ #puts "Method missing in XML::Document: #{symbol}"
113
+ singleton_method(symbol,*args,&block) || super(symbol,*args,&block)
114
+ end
115
+ def to_s
116
+ to_xml
117
+ end
118
+ end
119
+ end
120
+
121
+ module HTML
122
+ class Document < XML::Document
123
+ def initialize(title)
124
+ super 'HTML'
125
+ add_singleton_elements ['head']
126
+ add_singleton_elements ['body']
127
+ head.title << title
128
+ end
129
+ # Pass any unknown methods down to body
130
+ def method_missing(symbol,*args,&block)
131
+ singleton_method(symbol,*args,&block) ||
132
+ singleton_method(:body).send(symbol, *args, &block)
133
+ end
134
+ def self.test
135
+ doc = XML::Document.new "HTML"
136
+ doc.head.title << "Test HTML Document"
137
+ doc.body.h1 << "Header One"
138
+
139
+ puts doc.to_s
140
+
141
+ doc = HTML::Document.new 'Another test HTML Document'
142
+ doc.body.h1 << 'Header Two'
143
+ doc.table do |t|
144
+ t.tr{|r| r.th << :one;r.th << :two}
145
+ t.tr{|r| r.td << 1;r.td << 2}
146
+ end
147
+
148
+ puts doc.to_s
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'amanzi-sld'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,47 @@
1
+ require 'helper'
2
+ require 'differ'
3
+
4
+ class TestFile < Test::Unit::TestCase
5
+ # should "probably rename this file and start testing for real" do
6
+ # flunk "hey buddy, you should probably rename this file and start testing for real"
7
+ # end
8
+ def show_diff(results,expected)
9
+ puts "Results: #{results.class.to_s}"
10
+ puts "Expected: #{expected.class.to_s}"
11
+ puts "Results: #{results.inspect[0..100]}"
12
+ puts "Expected: #{expected.inspect[0..100]}"
13
+ diff = Differ.diff_by_line(results,expected)
14
+ puts diff.methods.join(', ')
15
+ # puts diff.inspect
16
+ puts diff.format_as :color
17
+ end
18
+ def test_file(file,expect)
19
+ @results = `ruby -I lib #{file}`
20
+
21
+ if File.exist? expect
22
+ expected = File.open(expect).read
23
+ if expected.length != @results.length
24
+ puts "Got different results: #{expected.length} != #{@results.length}"
25
+ show_diff(@results,expected)
26
+ false
27
+ else
28
+ true
29
+ end
30
+ else
31
+ File.open(@expect,'w') do |file|
32
+ file.puts @results
33
+ end
34
+ puts "Wrote first time run results to #{@expect}"
35
+ end
36
+ end
37
+
38
+ context "Test file" do
39
+ setup do
40
+ @file = 'examples/test.rb'
41
+ @expect = 'examples/test.sld'
42
+ end
43
+ should "produce expected output" do
44
+ assert test_file @file, @expect
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,123 @@
1
+ require 'helper'
2
+
3
+ class TestXML < Test::Unit::TestCase
4
+ context "An SLD document" do
5
+ setup do
6
+ @doc = Amanzi::SLD::Document.new 'Test SLD Document'
7
+ end
8
+ should "contain an XML header" do
9
+ #puts "Have SLD document: #{@doc}"
10
+ assert @doc.to_s =~ /^\<\?xml/
11
+ end
12
+ should "have a StyledLayerDescriptor->NamedLayer->UserStyle->Name tree" do
13
+ assert_equal @doc.name, 'StyledLayerDescriptor'
14
+ assert_equal (layer = @doc.children[0]).name, 'NamedLayer'
15
+ assert_equal layer.children[0].name, 'Name'
16
+ assert_equal (style = layer.children[1]).name, 'UserStyle'
17
+ assert_equal style.children[0].name, 'Name'
18
+ assert_equal 2, layer.children.length
19
+ end
20
+
21
+ context "with some line styles" do
22
+ setup do
23
+ @doc.comment "Add a simple line style"
24
+ @doc.add_line_symbolizer :stroke_width => 5
25
+ @doc.comment "Add a more complex line style with filter"
26
+ @doc.add_line_symbolizer :stroke_width => 5, :stroke => '#2080a0' do |f|
27
+ f.geometry = 'LineString'
28
+ end
29
+ end
30
+ should "have two LineSymbolizers" do
31
+ #puts "Have SLD document: #{@doc}"
32
+ tags = @doc.to_s.split(/[\r\n]+/).grep(/\<LineSymbolizer/i)
33
+ assert_equal 2, tags.length
34
+ end
35
+ should "have a geometry type function call" do
36
+ tags = @doc.to_s.split(/[\r\n]+/).grep(/\<ogc\:Function/i)
37
+ assert_equal 1, tags.length
38
+ assert /geometryType/.match tags[0]
39
+ end
40
+ end
41
+
42
+ context "with polygon style and complex filter" do
43
+ setup do
44
+ @doc.comment "Polygon with complex Filter"
45
+ @doc.add_polygon_symbolizer(:stroke_width => 2, :stroke => '#dddddd', :fill => '#aaaaaa', :fill_opacity => 0.4) do |f|
46
+ f.op(:and) do |f|
47
+ f.geometry = 'Polygon'
48
+ f.op(:or) do |f|
49
+ f.property.not_exists? :highway
50
+ f.property.exists? :waterway
51
+ f.property[:natural] = 'water'
52
+ end
53
+ end
54
+ end
55
+ end
56
+ should "have one PolygonSymbolizers" do
57
+ #puts "Have SLD document: #{@doc}"
58
+ assert_equal 1, @doc.to_s.split(/[\r\n]+/).grep(/\<PolygonSymbolizer/i).length
59
+ assert_equal 1, @doc.to_s.split(/[\r\n]+/).grep(/\<\/PolygonSymbolizer/i).length
60
+ end
61
+ should "have a geometry type function call" do
62
+ tags = @doc.to_s.split(/[\r\n]+/).grep(/\<ogc\:Function/i)
63
+ assert_equal 1, tags.length
64
+ assert /geometryType/.match tags[0]
65
+ end
66
+ end
67
+
68
+ context "with multiple symbolizers using the same filter rules" do
69
+ setup do
70
+ @doc.comment "Multiple symbolizers and complex filter"
71
+ @doc.
72
+ add_line_symbolizer(:stroke_width => 7, :stroke => '#303030').
73
+ add_line_symbolizer(:stroke_width => 5, :stroke => '#e0e0ff') do |f|
74
+ f.op(:and) do |f|
75
+ f.geometry = 'LineString'
76
+ f.property.exists? :highway
77
+ f.op(:or) do |f|
78
+ f.property[:highway] = 'secondary'
79
+ f.property[:highway] = 'tertiary'
80
+ end
81
+ end
82
+ end
83
+ end
84
+ should "have two LineSymbolizers" do
85
+ #puts "Have SLD document: #{@doc}"
86
+ assert_equal 2, @doc.to_s.split(/[\r\n]+/).grep(/\<LineSymbolizer/i).length
87
+ assert_equal 2, @doc.to_s.split(/[\r\n]+/).grep(/\<\/LineSymbolizer/i).length
88
+ end
89
+ should "have a geometry type function call" do
90
+ tags = @doc.to_s.split(/[\r\n]+/).grep(/\<ogc\:Function/i)
91
+ assert_equal 1, tags.length
92
+ assert /geometryType/.match tags[0]
93
+ end
94
+ should "have four CssParameter tags" do
95
+ assert_equal 4, @doc.to_s.split(/[\r\n]+/).grep(/\<CssParameter/i).length
96
+ assert_equal 4, @doc.to_s.split(/[\r\n]+/).grep(/\<\/CssParameter/i).length
97
+ end
98
+ should "have an rule->filter->and tree with three children" do
99
+ assert_equal 'StyledLayerDescriptor', @doc.name
100
+ assert_equal 'NamedLayer', (layer = @doc.children[0]).name
101
+ assert_equal 'UserStyle', (style = layer.children[1]).name
102
+ assert_equal 3, style.children.length
103
+ assert_equal 'FeatureTypeStyle', (fstyle = style.children[2]).name
104
+ assert_equal 'Rule', (rule = fstyle.children[0]).name
105
+ assert_equal 3, rule.children.length
106
+ assert_equal 'Filter', (filter = rule.children[0]).name
107
+ assert_equal 1, filter.children.length
108
+ assert_equal 'And', (andtag = filter.children[0]).name
109
+ assert_equal 3, andtag.children.length
110
+ assert_equal 'PropertyIsEqualTo', (geom = andtag.children[0]).name
111
+ assert_equal 2, geom.children.length
112
+ assert_equal 'Literal', (gname = geom.children[1]).name
113
+ assert_equal 'LineString', gname.children[0]
114
+ assert_equal 'Or', (props = andtag.children[2]).name
115
+ assert_equal 2, props.children.length
116
+ assert_equal 'PropertyIsEqualTo', (propB = props.children[1]).name
117
+ assert_equal 'PropertyName', propB.children[0].name
118
+ assert_equal 'highway', propB.children[0].contents
119
+ assert_equal 'tertiary', propB.children[1].contents
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,70 @@
1
+ require 'helper'
2
+
3
+ class TestXML < Test::Unit::TestCase
4
+ context "An XML document" do
5
+ setup do
6
+ @doc = Amanzi::XML::Document.new 'Test'
7
+ end
8
+ should "contain an XML header" do
9
+ assert @doc.to_s =~ /^\<\?xml/
10
+ end
11
+ context "with some tags" do
12
+ setup do
13
+ @doc.data.body do |body|
14
+ body.head << "Header"
15
+ body.content << "Some text"
16
+ end
17
+ end
18
+ should "have only one body" do
19
+ #puts "Have XML document: #{@doc}"
20
+ body_tags = @doc.to_s.split(/[\r\n]+/).grep(/\<body/i)
21
+ assert_equal 1, body_tags.length
22
+ end
23
+ should "have an data->body with two child tags" do
24
+ assert_equal 'data', (data = @doc.children[0]).name.downcase
25
+ assert_equal 'body', (body = data.children[0]).name.downcase
26
+ assert_equal 2, body.children.length
27
+ end
28
+ end
29
+ end
30
+
31
+ context "An HTML document" do
32
+ setup do
33
+ @doc = Amanzi::HTML::Document.new 'Test HTML Document'
34
+ end
35
+ should "contain an XML header" do
36
+ assert @doc.to_s =~ /^\<\?xml/
37
+ end
38
+ context "with some tags" do
39
+ setup do
40
+ @doc.body.h1 << "Header"
41
+ @doc.body.p << "Some text"
42
+ @doc.body.p << "Some more text"
43
+ @doc.body.table do |t|
44
+ t.tr do |tr|
45
+ tr.td << 'a'
46
+ tr.td << 'b'
47
+ end
48
+ t.tr do |tr|
49
+ tr.td << '1'
50
+ tr.td << '2'
51
+ end
52
+ end
53
+ end
54
+ should "have only one body" do
55
+ #puts "Have HTML document: #{@doc}"
56
+ body_tags = @doc.to_s.split(/[\r\n]+/).grep(/\<body/i)
57
+ assert_equal 1, body_tags.length
58
+ end
59
+ should "have four table cell tags" do
60
+ assert_equal 4, @doc.to_s.split(/[\r\n]+/).grep(/\<td/i).length
61
+ assert_equal 4, @doc.to_s.split(/[\r\n]+/).grep(/\<\/td/i).length
62
+ end
63
+ should "have an html->body with four child tags" do
64
+ assert_equal 'head', (head = @doc.children[0]).name.downcase
65
+ assert_equal 'body', (body = @doc.children[1]).name.downcase
66
+ assert_equal 4, body.children.length
67
+ end
68
+ end
69
+ end
70
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: amanzi-sld
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Craig Taverner
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-02 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thoughtbot-shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: differ
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 9
44
+ segments:
45
+ - 0
46
+ - 1
47
+ version: "0.1"
48
+ type: :development
49
+ version_requirements: *id002
50
+ description: Map styles are often defined using SLD, or Style Layer Descriptor documents. These XML documents are very long, verbose and complex to maintain. Amanzi:SLD is a simpler DSL designed to generate SLD documents, but using a very much simpler syntax. Many common cases might be a single line only, while the simplest SLD is usually a dozen lines or more.
51
+ email: craig@amanzi.com
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files:
57
+ - LICENSE
58
+ - README.rdoc
59
+ files:
60
+ - .document
61
+ - .gitignore
62
+ - LICENSE
63
+ - README.rdoc
64
+ - Rakefile
65
+ - VERSION
66
+ - amanzi-sld.gemspec
67
+ - examples/osm.rb
68
+ - examples/osm_highway_shp.rb
69
+ - examples/test.rb
70
+ - examples/test.sld
71
+ - lib/amanzi-sld.rb
72
+ - lib/amanzi/sld.rb
73
+ - lib/amanzi/xml.rb
74
+ - test/helper.rb
75
+ - test/test_file.rb
76
+ - test/test_sld.rb
77
+ - test/test_xml.rb
78
+ has_rdoc: true
79
+ homepage: http://github.com/craigtaverner/amanzi-sld
80
+ licenses: []
81
+
82
+ post_install_message:
83
+ rdoc_options:
84
+ - --charset=UTF-8
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ requirements: []
106
+
107
+ rubyforge_project:
108
+ rubygems_version: 1.3.7
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: A Ruby DSL for simpler SLD creation for styling maps
112
+ test_files:
113
+ - test/test_file.rb
114
+ - test/test_xml.rb
115
+ - test/test_sld.rb
116
+ - test/helper.rb
117
+ - examples/osm.rb
118
+ - examples/test.rb
119
+ - examples/osm_highway_shp.rb