amanzi-sld 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|