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.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +131 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/amanzi-sld.gemspec +70 -0
- data/examples/osm.rb +55 -0
- data/examples/osm_highway_shp.rb +103 -0
- data/examples/test.rb +95 -0
- data/examples/test.sld +232 -0
- data/lib/amanzi-sld.rb +1 -0
- data/lib/amanzi/sld.rb +222 -0
- data/lib/amanzi/xml.rb +152 -0
- data/test/helper.rb +10 -0
- data/test/test_file.rb +47 -0
- data/test/test_sld.rb +123 -0
- data/test/test_xml.rb +70 -0
- metadata +119 -0
data/examples/test.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This script uses the amanzi-sld DSL to create a sample SLD file
|
4
|
+
# containing a few examples. The examples are done in a few different
|
5
|
+
# ways to demonstrate the SLD syntax.
|
6
|
+
|
7
|
+
require 'amanzi/sld'
|
8
|
+
|
9
|
+
Amanzi::SLD::Config.config[:geometry_property] = 'the_geom'
|
10
|
+
#Amanzi::SLD::Config.config[:verbose] = true
|
11
|
+
|
12
|
+
sld = Amanzi::SLD::Document.new "Example"
|
13
|
+
|
14
|
+
# Create XML using the underlying pure-XML DSL from Amanzi::XML
|
15
|
+
sld.comment "Pure-XML DSL"
|
16
|
+
sld.feature_type_style.rule.line_symbolizer.stroke do |stroke|
|
17
|
+
stroke.css_parameter(:name => "stroke") << '#dddddd'
|
18
|
+
stroke.css_parameter(:name => "stroke-width") << '1'
|
19
|
+
end
|
20
|
+
|
21
|
+
# Now create some SLD XML using the higher level SLD-specific syntax
|
22
|
+
|
23
|
+
# First a simple example, a LineSymbolizer with no filter
|
24
|
+
sld.comment "Simple Line DSL"
|
25
|
+
sld.add_line_symbolizer(:stroke_width => 2, :stroke => '#dddddd')
|
26
|
+
|
27
|
+
# Now try one with a filter, but specified using XML DSL
|
28
|
+
sld.comment "Line with Filter, using XML DSL"
|
29
|
+
sld.feature_type_style.rule do |rule|
|
30
|
+
rule.filter.ns(:ogc).property_is_equal_to do |f|
|
31
|
+
f.function(:name => 'geometryType').property_name << 'the_geom'
|
32
|
+
f.literal << 'Polygon'
|
33
|
+
end
|
34
|
+
rule.polygon_symbolizer do |s|
|
35
|
+
s.fill do |f|
|
36
|
+
f.css_parameter(:name=>"fill") << '#aaaaaa'
|
37
|
+
f.css_parameter(:name=>"fill-opacity") << '0.4'
|
38
|
+
end
|
39
|
+
s.stroke.css_parameter(:name => "stroke") << '#ffe0e0'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# And now see how simple these can be with the SLD syntax
|
44
|
+
sld.comment "Line with Filter, using SLD DSL"
|
45
|
+
sld.add_line_symbolizer(:stroke_width => 2, :stroke => '#dddddd') do |f|
|
46
|
+
f.geometry = 'LineString'
|
47
|
+
end
|
48
|
+
sld.comment "Polygon with Filter, using SLD DSL"
|
49
|
+
sld.add_polygon_symbolizer(:stroke_width => 2, :stroke => '#dddddd', :fill => '#aaaaaa', :fill_opacity => 0.4) do |f|
|
50
|
+
f.geometry = 'Polygon'
|
51
|
+
end
|
52
|
+
sld.comment "Polygon with Filter, using SLD DSL, and more compact polygon filtering syntax"
|
53
|
+
sld.add_polygon_symbolizer(:stroke_width => 2, :stroke => '#dddddd', :fill => '#aaaaaa', :fill_opacity => 0.4, :geometry => 'Polygon')
|
54
|
+
|
55
|
+
# Using SLD syntax for Filtering makes it simler to do really complex things
|
56
|
+
sld.comment "Polygon with complex Filter"
|
57
|
+
sld.add_polygon_symbolizer(:stroke_width => 2, :stroke => '#dddddd', :fill => '#aaaaaa', :fill_opacity => 0.4) do |f|
|
58
|
+
f.op(:and) do |f|
|
59
|
+
f.geometry = 'Polygon'
|
60
|
+
f.op(:or) do |f|
|
61
|
+
f.property.not_exists? :highway
|
62
|
+
f.property.exists? :waterway
|
63
|
+
f.property[:natural] = 'water'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Combining the compact geometry option with other filter settings
|
69
|
+
sld.comment "Polygon with combined simple and complex Filter"
|
70
|
+
sld.add_polygon_symbolizer(:stroke_width => 2, :stroke => '#dddddd', :fill => '#aaaaaa', :fill_opacity => 0.4, :geometry => 'Polygon') do |f|
|
71
|
+
f.op(:or) do |f|
|
72
|
+
f.property.not_exists? :highway
|
73
|
+
f.property.exists? :waterway
|
74
|
+
f.property[:natural] = 'water'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Adding a set of symbolizers within the same rules filter
|
79
|
+
sld.comment "Multiple symbolizers and complex filter"
|
80
|
+
sld.
|
81
|
+
add_line_symbolizer(:stroke_width => 7, :stroke => '#303030').
|
82
|
+
add_line_symbolizer(:stroke_width => 5, :stroke => '#e0e0ff') do |f|
|
83
|
+
f.op(:and) do |f|
|
84
|
+
f.property.exists? :highway
|
85
|
+
f.op(:or) do |f|
|
86
|
+
f.property[:highway] = 'secondary'
|
87
|
+
f.property[:highway] = 'tertiary'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
puts sld.to_xml(:tab => ' ')
|
93
|
+
|
94
|
+
#HTML::Document.test
|
95
|
+
|
data/examples/test.sld
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
<StyledLayerDescriptor xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/sld">
|
3
|
+
<NamedLayer>
|
4
|
+
<Name>Example</Name>
|
5
|
+
<UserStyle>
|
6
|
+
<Name>Example</Name>
|
7
|
+
<!-- Pure-XML DSL -->
|
8
|
+
<FeatureTypeStyle>
|
9
|
+
<Rule>
|
10
|
+
<LineSymbolizer>
|
11
|
+
<Stroke>
|
12
|
+
<CssParameter name="stroke">#dddddd</CssParameter>
|
13
|
+
<CssParameter name="stroke-width">1</CssParameter>
|
14
|
+
</Stroke>
|
15
|
+
</LineSymbolizer>
|
16
|
+
</Rule>
|
17
|
+
</FeatureTypeStyle>
|
18
|
+
<!-- Simple Line DSL -->
|
19
|
+
<FeatureTypeStyle>
|
20
|
+
<Rule>
|
21
|
+
<LineSymbolizer>
|
22
|
+
<Stroke>
|
23
|
+
<CssParameter name="stroke-width">2</CssParameter>
|
24
|
+
<CssParameter name="stroke">#dddddd</CssParameter>
|
25
|
+
</Stroke>
|
26
|
+
</LineSymbolizer>
|
27
|
+
</Rule>
|
28
|
+
</FeatureTypeStyle>
|
29
|
+
<!-- Line with Filter, using XML DSL -->
|
30
|
+
<FeatureTypeStyle>
|
31
|
+
<Rule>
|
32
|
+
<ogc:Filter>
|
33
|
+
<ogc:PropertyIsEqualTo>
|
34
|
+
<ogc:Function name="geometryType">
|
35
|
+
<ogc:PropertyName>the_geom</ogc:PropertyName>
|
36
|
+
</ogc:Function>
|
37
|
+
<ogc:Literal>Polygon</ogc:Literal>
|
38
|
+
</ogc:PropertyIsEqualTo>
|
39
|
+
</ogc:Filter>
|
40
|
+
<PolygonSymbolizer>
|
41
|
+
<Fill>
|
42
|
+
<CssParameter name="fill">#aaaaaa</CssParameter>
|
43
|
+
<CssParameter name="fill-opacity">0.4</CssParameter>
|
44
|
+
</Fill>
|
45
|
+
<Stroke>
|
46
|
+
<CssParameter name="stroke">#ffe0e0</CssParameter>
|
47
|
+
</Stroke>
|
48
|
+
</PolygonSymbolizer>
|
49
|
+
</Rule>
|
50
|
+
</FeatureTypeStyle>
|
51
|
+
<!-- Line with Filter, using SLD DSL -->
|
52
|
+
<FeatureTypeStyle>
|
53
|
+
<Rule>
|
54
|
+
<ogc:Filter>
|
55
|
+
<ogc:PropertyIsEqualTo>
|
56
|
+
<ogc:Function name="geometryType">
|
57
|
+
<ogc:PropertyName>the_geom</ogc:PropertyName>
|
58
|
+
</ogc:Function>
|
59
|
+
<ogc:Literal>LineString</ogc:Literal>
|
60
|
+
</ogc:PropertyIsEqualTo>
|
61
|
+
</ogc:Filter>
|
62
|
+
<LineSymbolizer>
|
63
|
+
<Stroke>
|
64
|
+
<CssParameter name="stroke-width">2</CssParameter>
|
65
|
+
<CssParameter name="stroke">#dddddd</CssParameter>
|
66
|
+
</Stroke>
|
67
|
+
</LineSymbolizer>
|
68
|
+
</Rule>
|
69
|
+
</FeatureTypeStyle>
|
70
|
+
<!-- Polygon with Filter, using SLD DSL -->
|
71
|
+
<FeatureTypeStyle>
|
72
|
+
<Rule>
|
73
|
+
<ogc:Filter>
|
74
|
+
<ogc:PropertyIsEqualTo>
|
75
|
+
<ogc:Function name="geometryType">
|
76
|
+
<ogc:PropertyName>the_geom</ogc:PropertyName>
|
77
|
+
</ogc:Function>
|
78
|
+
<ogc:Literal>Polygon</ogc:Literal>
|
79
|
+
</ogc:PropertyIsEqualTo>
|
80
|
+
</ogc:Filter>
|
81
|
+
<PolygonSymbolizer>
|
82
|
+
<Fill>
|
83
|
+
<CssParameter name="fill-opacity">0.4</CssParameter>
|
84
|
+
<CssParameter name="fill">#aaaaaa</CssParameter>
|
85
|
+
</Fill>
|
86
|
+
<Stroke>
|
87
|
+
<CssParameter name="stroke-width">2</CssParameter>
|
88
|
+
<CssParameter name="stroke">#dddddd</CssParameter>
|
89
|
+
</Stroke>
|
90
|
+
</PolygonSymbolizer>
|
91
|
+
</Rule>
|
92
|
+
</FeatureTypeStyle>
|
93
|
+
<!-- Polygon with Filter, using SLD DSL, and more compact polygon filtering syntax -->
|
94
|
+
<FeatureTypeStyle>
|
95
|
+
<Rule>
|
96
|
+
<ogc:Filter>
|
97
|
+
<ogc:PropertyIsEqualTo>
|
98
|
+
<ogc:Function name="geometryType">
|
99
|
+
<ogc:PropertyName>the_geom</ogc:PropertyName>
|
100
|
+
</ogc:Function>
|
101
|
+
<ogc:Literal>Polygon</ogc:Literal>
|
102
|
+
</ogc:PropertyIsEqualTo>
|
103
|
+
</ogc:Filter>
|
104
|
+
<PolygonSymbolizer>
|
105
|
+
<Fill>
|
106
|
+
<CssParameter name="fill-opacity">0.4</CssParameter>
|
107
|
+
<CssParameter name="fill">#aaaaaa</CssParameter>
|
108
|
+
</Fill>
|
109
|
+
<Stroke>
|
110
|
+
<CssParameter name="stroke-width">2</CssParameter>
|
111
|
+
<CssParameter name="stroke">#dddddd</CssParameter>
|
112
|
+
</Stroke>
|
113
|
+
</PolygonSymbolizer>
|
114
|
+
</Rule>
|
115
|
+
</FeatureTypeStyle>
|
116
|
+
<!-- Polygon with complex Filter -->
|
117
|
+
<FeatureTypeStyle>
|
118
|
+
<Rule>
|
119
|
+
<ogc:Filter>
|
120
|
+
<ogc:And>
|
121
|
+
<ogc:PropertyIsEqualTo>
|
122
|
+
<ogc:Function name="geometryType">
|
123
|
+
<ogc:PropertyName>the_geom</ogc:PropertyName>
|
124
|
+
</ogc:Function>
|
125
|
+
<ogc:Literal>Polygon</ogc:Literal>
|
126
|
+
</ogc:PropertyIsEqualTo>
|
127
|
+
<ogc:Or>
|
128
|
+
<ogc:PropertyIsNull>
|
129
|
+
<ogc:PropertyName>highway</ogc:PropertyName>
|
130
|
+
</ogc:PropertyIsNull>
|
131
|
+
<ogc:Not>
|
132
|
+
<ogc:PropertyIsNull>
|
133
|
+
<ogc:PropertyName>waterway</ogc:PropertyName>
|
134
|
+
</ogc:PropertyIsNull>
|
135
|
+
</ogc:Not>
|
136
|
+
<ogc:PropertyIsEqualTo>
|
137
|
+
<ogc:PropertyName>natural</ogc:PropertyName>
|
138
|
+
<ogc:Literal>water</ogc:Literal>
|
139
|
+
</ogc:PropertyIsEqualTo>
|
140
|
+
</ogc:Or>
|
141
|
+
</ogc:And>
|
142
|
+
</ogc:Filter>
|
143
|
+
<PolygonSymbolizer>
|
144
|
+
<Fill>
|
145
|
+
<CssParameter name="fill-opacity">0.4</CssParameter>
|
146
|
+
<CssParameter name="fill">#aaaaaa</CssParameter>
|
147
|
+
</Fill>
|
148
|
+
<Stroke>
|
149
|
+
<CssParameter name="stroke-width">2</CssParameter>
|
150
|
+
<CssParameter name="stroke">#dddddd</CssParameter>
|
151
|
+
</Stroke>
|
152
|
+
</PolygonSymbolizer>
|
153
|
+
</Rule>
|
154
|
+
</FeatureTypeStyle>
|
155
|
+
<!-- Polygon with combined simple and complex Filter -->
|
156
|
+
<FeatureTypeStyle>
|
157
|
+
<Rule>
|
158
|
+
<ogc:Filter>
|
159
|
+
<ogc:And>
|
160
|
+
<ogc:PropertyIsEqualTo>
|
161
|
+
<ogc:Function name="geometryType">
|
162
|
+
<ogc:PropertyName>the_geom</ogc:PropertyName>
|
163
|
+
</ogc:Function>
|
164
|
+
<ogc:Literal>Polygon</ogc:Literal>
|
165
|
+
</ogc:PropertyIsEqualTo>
|
166
|
+
<ogc:Or>
|
167
|
+
<ogc:PropertyIsNull>
|
168
|
+
<ogc:PropertyName>highway</ogc:PropertyName>
|
169
|
+
</ogc:PropertyIsNull>
|
170
|
+
<ogc:Not>
|
171
|
+
<ogc:PropertyIsNull>
|
172
|
+
<ogc:PropertyName>waterway</ogc:PropertyName>
|
173
|
+
</ogc:PropertyIsNull>
|
174
|
+
</ogc:Not>
|
175
|
+
<ogc:PropertyIsEqualTo>
|
176
|
+
<ogc:PropertyName>natural</ogc:PropertyName>
|
177
|
+
<ogc:Literal>water</ogc:Literal>
|
178
|
+
</ogc:PropertyIsEqualTo>
|
179
|
+
</ogc:Or>
|
180
|
+
</ogc:And>
|
181
|
+
</ogc:Filter>
|
182
|
+
<PolygonSymbolizer>
|
183
|
+
<Fill>
|
184
|
+
<CssParameter name="fill-opacity">0.4</CssParameter>
|
185
|
+
<CssParameter name="fill">#aaaaaa</CssParameter>
|
186
|
+
</Fill>
|
187
|
+
<Stroke>
|
188
|
+
<CssParameter name="stroke-width">2</CssParameter>
|
189
|
+
<CssParameter name="stroke">#dddddd</CssParameter>
|
190
|
+
</Stroke>
|
191
|
+
</PolygonSymbolizer>
|
192
|
+
</Rule>
|
193
|
+
</FeatureTypeStyle>
|
194
|
+
<!-- Multiple symbolizers and complex filter -->
|
195
|
+
<FeatureTypeStyle>
|
196
|
+
<Rule>
|
197
|
+
<ogc:Filter>
|
198
|
+
<ogc:And>
|
199
|
+
<ogc:Not>
|
200
|
+
<ogc:PropertyIsNull>
|
201
|
+
<ogc:PropertyName>highway</ogc:PropertyName>
|
202
|
+
</ogc:PropertyIsNull>
|
203
|
+
</ogc:Not>
|
204
|
+
<ogc:Or>
|
205
|
+
<ogc:PropertyIsEqualTo>
|
206
|
+
<ogc:PropertyName>highway</ogc:PropertyName>
|
207
|
+
<ogc:Literal>secondary</ogc:Literal>
|
208
|
+
</ogc:PropertyIsEqualTo>
|
209
|
+
<ogc:PropertyIsEqualTo>
|
210
|
+
<ogc:PropertyName>highway</ogc:PropertyName>
|
211
|
+
<ogc:Literal>tertiary</ogc:Literal>
|
212
|
+
</ogc:PropertyIsEqualTo>
|
213
|
+
</ogc:Or>
|
214
|
+
</ogc:And>
|
215
|
+
</ogc:Filter>
|
216
|
+
<LineSymbolizer>
|
217
|
+
<Stroke>
|
218
|
+
<CssParameter name="stroke-width">7</CssParameter>
|
219
|
+
<CssParameter name="stroke">#303030</CssParameter>
|
220
|
+
</Stroke>
|
221
|
+
</LineSymbolizer>
|
222
|
+
<LineSymbolizer>
|
223
|
+
<Stroke>
|
224
|
+
<CssParameter name="stroke-width">5</CssParameter>
|
225
|
+
<CssParameter name="stroke">#e0e0ff</CssParameter>
|
226
|
+
</Stroke>
|
227
|
+
</LineSymbolizer>
|
228
|
+
</Rule>
|
229
|
+
</FeatureTypeStyle>
|
230
|
+
</UserStyle>
|
231
|
+
</NamedLayer>
|
232
|
+
</StyledLayerDescriptor>
|
data/lib/amanzi-sld.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'amanzi/sld'
|
data/lib/amanzi/sld.rb
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
#/usr/bin/env ruby
|
2
|
+
|
3
|
+
# The Amanzi:SLD module contains classes for a DSL for specifying
|
4
|
+
# StyleLayerDescriptor XML documents in a much simpler syntax than
|
5
|
+
# the usual XML syntax. It is based on the Amanzi::XML DSL which
|
6
|
+
# by itself already makes the syntax much simpler. You can access
|
7
|
+
# the underlying Amanzi::XML syntax as well, should you wish, but
|
8
|
+
# The SLD syntax makes common things much easier.
|
9
|
+
#
|
10
|
+
# For example, specify a PolygonSymbolizer like this:
|
11
|
+
# require 'amanzi/sld'
|
12
|
+
# sld = Amanzi::SLD::Document.new "Example"
|
13
|
+
# sld.add_polygon_symbolizer :stroke_width => 2, :stroke => '#dddddd', :fill => '#aaaaaa', :fill_opacity => 0.4
|
14
|
+
|
15
|
+
require 'amanzi/xml'
|
16
|
+
|
17
|
+
module Amanzi
|
18
|
+
module SLD
|
19
|
+
class Config
|
20
|
+
attr_accessor :settings
|
21
|
+
def self.config(options={})
|
22
|
+
@@instance ||= Config.new(options)
|
23
|
+
end
|
24
|
+
def initialize(options={})
|
25
|
+
@settings = options
|
26
|
+
end
|
27
|
+
def []=(key,value)
|
28
|
+
settings[key] = value
|
29
|
+
end
|
30
|
+
def [](key)
|
31
|
+
settings[key]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
module Logger
|
35
|
+
def puts *args
|
36
|
+
STDOUT.puts(*args) if(Config.config[:verbose])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
class Document < XML::Document
|
40
|
+
include Logger
|
41
|
+
attr_reader :sld_name, :style_name, :name, :geometry_property
|
42
|
+
def initialize(name,options={})
|
43
|
+
super 'StyledLayerDescriptor'
|
44
|
+
self['version'] = '1.0.0'
|
45
|
+
self['xmlns'] = "http://www.opengis.net/sld"
|
46
|
+
self['xmlns:ogc'] ="http://www.opengis.net/ogc"
|
47
|
+
self['xmlns:xlink'] = "http://www.w3.org/1999/xlink"
|
48
|
+
self['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance"
|
49
|
+
self['xsi:schemaLocation'] = "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
|
50
|
+
add_singleton_elements ['named_layer','user_style']
|
51
|
+
singleton_method(:named_layer).insert_child(0,'Name') << name
|
52
|
+
singleton_method(:user_style).insert_child(0,'Name') << name
|
53
|
+
end
|
54
|
+
# Pass any unknown methods down to user_style
|
55
|
+
def method_missing(symbol,*args,&block)
|
56
|
+
puts "Looking for SLD document method: #{symbol}"
|
57
|
+
singleton_method(symbol,*args,&block) ||
|
58
|
+
singleton_method(:user_style).send(symbol, *args, &block)
|
59
|
+
end
|
60
|
+
def add_line_symbolizer(options={},*args,&block)
|
61
|
+
RuleBuilder.new(self.feature_type_style.rule).add_line_symbolizer(options,*args,&block)
|
62
|
+
end
|
63
|
+
def add_polygon_symbolizer(options={},*args,&block)
|
64
|
+
RuleBuilder.new(self.feature_type_style.rule).add_polygon_symbolizer(options,*args,&block)
|
65
|
+
end
|
66
|
+
def add_text_symbolizer(options={},*args,&block)
|
67
|
+
RuleBuilder.new(self.feature_type_style.rule).add_text_symbolizer(options,*args,&block)
|
68
|
+
end
|
69
|
+
def add_rule(options={})
|
70
|
+
puts "Adding a generic rule: #{options.inspect}"
|
71
|
+
self.feature_type_style do |fs|
|
72
|
+
rule_builder = RuleBuilder.new(rule)
|
73
|
+
yield rule_builder if(block_given?)
|
74
|
+
rule_builder
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
class ElementWrapper
|
79
|
+
include Logger
|
80
|
+
attr_reader :element
|
81
|
+
def initialize(element)
|
82
|
+
@element = element
|
83
|
+
end
|
84
|
+
def method_missing(symbol,*args,&block)
|
85
|
+
puts "Method '#{symbol}' missing on Element Wrapper: #{self.inspect}"
|
86
|
+
element.send(symbol,*args,&block)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
class RuleBuilder < ElementWrapper
|
90
|
+
alias_method :rule, :element
|
91
|
+
def initialize(rule)
|
92
|
+
super rule
|
93
|
+
end
|
94
|
+
def style_it(it,prefix,options={})
|
95
|
+
options.each do |k,v|
|
96
|
+
if k.to_s =~ /^#{prefix}/
|
97
|
+
it.css_parameter(:name => k.to_s.gsub(/_/,'-')) << v
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
def style_stroke(stroke,options={})
|
102
|
+
style_it(stroke,:stroke,options)
|
103
|
+
end
|
104
|
+
def style_fill(fill,options={})
|
105
|
+
style_it(fill,:fill,options)
|
106
|
+
end
|
107
|
+
def style_font(font,options={})
|
108
|
+
style_it(font,:font,options)
|
109
|
+
end
|
110
|
+
def update_filter_block(options,&block)
|
111
|
+
new_block = block
|
112
|
+
self.max_scale_denominator << options[:max_scale].to_f if(options[:max_scale])
|
113
|
+
self.min_scale_denominator << options[:min_scale].to_f if(options[:min_scale])
|
114
|
+
if(options[:geometry])
|
115
|
+
if(block)
|
116
|
+
new_block = Proc.new do |f|
|
117
|
+
f.op(:and) do |f|
|
118
|
+
f.geometry = options[:geometry]
|
119
|
+
block.call f
|
120
|
+
end
|
121
|
+
end
|
122
|
+
else
|
123
|
+
new_block = Proc.new {|f| f.geometry = options[:geometry]}
|
124
|
+
end
|
125
|
+
end
|
126
|
+
new_block
|
127
|
+
end
|
128
|
+
def add_line_symbolizer(options={},*args,&block)
|
129
|
+
options[:stroke] ||= '#000000'
|
130
|
+
options[:stroke_width] ||= 1
|
131
|
+
puts "RuleBuilder:Adding line symbolizer with options: #{options.inspect}"
|
132
|
+
block = update_filter_block(options,&block)
|
133
|
+
block.call FilterBuilder.new(rule.insert_child(0,'Filter').ns(:ogc)) if(block)
|
134
|
+
style_stroke(rule.line_symbolizer.stroke,options)
|
135
|
+
self
|
136
|
+
end
|
137
|
+
def add_polygon_symbolizer(options={},*args,&block)
|
138
|
+
options[:fill] ||= '#b0b0b0'
|
139
|
+
puts "Adding polygon symbolizer with options: #{options.inspect}"
|
140
|
+
block = update_filter_block(options,&block)
|
141
|
+
block.call FilterBuilder.new(rule.insert_child(0,'Filter').ns(:ogc)) if(block)
|
142
|
+
rule.polygon_symbolizer do |p|
|
143
|
+
style_fill(p.fill,options)
|
144
|
+
style_stroke(p.stroke,options)
|
145
|
+
end
|
146
|
+
self
|
147
|
+
end
|
148
|
+
def add_text_symbolizer(options={},*args,&block)
|
149
|
+
return self unless options[:text] || options[:property]
|
150
|
+
options[:font_family] ||= 'Times New Roman'
|
151
|
+
options[:font_style] ||= 'Normal'
|
152
|
+
options[:font_size] ||= 14
|
153
|
+
options[:font_weight] ||= 'bold'
|
154
|
+
options[:font_color] ||= '#101010'
|
155
|
+
options[:fill] ||= '#101010'
|
156
|
+
options[:halo_style] ||= {:fill => '#ffffbb', :fill_opacity => 0.85}
|
157
|
+
puts "Adding text symbolizer with options: #{options.inspect}"
|
158
|
+
block = update_filter_block(options,&block)
|
159
|
+
block.call FilterBuilder.new(rule.insert_child(0,'Filter').ns(:ogc)) if(block)
|
160
|
+
rule.text_symbolizer do |p|
|
161
|
+
if options[:property]
|
162
|
+
p.label.ogc__property_name << options[:property]
|
163
|
+
else
|
164
|
+
p.label.ogc__literal << options[:text]
|
165
|
+
end
|
166
|
+
style_font(p.font,options)
|
167
|
+
if options[:halo].to_i > 0
|
168
|
+
p.halo do |h|
|
169
|
+
h.radius.ogc__literal << options[:halo].to_i
|
170
|
+
style_fill(h.fill,options[:halo_style])
|
171
|
+
end
|
172
|
+
end
|
173
|
+
style_fill(p.fill,options)
|
174
|
+
end
|
175
|
+
self
|
176
|
+
end
|
177
|
+
end
|
178
|
+
class FilterBuilder < ElementWrapper
|
179
|
+
def initialize(filter)
|
180
|
+
super filter
|
181
|
+
puts "Created filter builder: #{element}"
|
182
|
+
end
|
183
|
+
def geometry=(type)
|
184
|
+
element.property_is_equal_to do |f|
|
185
|
+
f.function(:name => 'geometryType').property_name << (Config.config[:geometry_property] || 'geom')
|
186
|
+
f.literal << type
|
187
|
+
end
|
188
|
+
end
|
189
|
+
def property
|
190
|
+
@property ||= PropertyFilterBuilder.new(element)
|
191
|
+
end
|
192
|
+
def op(op_type)
|
193
|
+
op_type = op_type.to_s.intern
|
194
|
+
@op ||= {}
|
195
|
+
yield(@op[op_type] ||= BooleanFilterBuilder.new(element,op_type)) if(block_given?)
|
196
|
+
@op[op_type]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
class PropertyFilterBuilder < ElementWrapper
|
200
|
+
def initialize(filter)
|
201
|
+
super filter
|
202
|
+
end
|
203
|
+
def []=(key,value)
|
204
|
+
element.property_is_equal_to do |f|
|
205
|
+
f.property_name << key.to_s
|
206
|
+
f.literal << value.to_s
|
207
|
+
end
|
208
|
+
end
|
209
|
+
def exists? name
|
210
|
+
element.send(:not).property_is_null.property_name << name
|
211
|
+
end
|
212
|
+
def not_exists? name
|
213
|
+
element.property_is_null.property_name << name
|
214
|
+
end
|
215
|
+
end
|
216
|
+
class BooleanFilterBuilder < FilterBuilder
|
217
|
+
def initialize(filter,op)
|
218
|
+
super(filter.send(op))
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|