gb_mapfish_appserver 0.0.6 → 0.0.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 (52) hide show
  1. data/.gitignore +11 -0
  2. data/Gemfile +18 -0
  3. data/app/assets/images/gb_mapfish_appserver/.gitkeep +0 -0
  4. data/app/assets/javascripts/gb_mapfish_appserver/.gitkeep +0 -0
  5. data/app/assets/stylesheets/gb_mapfish_appserver/.gitkeep +0 -0
  6. data/app/controllers/print_controller.rb +5 -4
  7. data/app/models/layer.rb +6 -4
  8. data/app/models/topic.rb +14 -0
  9. data/app/views/topics/query.html.erb +1 -1
  10. data/gb_mapfish_appserver.gemspec +37 -0
  11. data/lib/gb_mapfish_appserver/version.rb +1 -1
  12. data/lib/generators/mapfish/install/install_generator.rb +4 -0
  13. data/lib/tasks/mapfile.rake +13 -9
  14. data/lib/tasks/templates/_infotable_auto.html.erb +0 -11
  15. data/script/rails +8 -0
  16. data/test/dummy/app/mailers/.gitkeep +0 -0
  17. data/test/dummy/app/models/.gitkeep +0 -0
  18. data/test/dummy/app/views/layers/custom/cascadingwms/_cascaded_info.html.erb +1 -1
  19. data/test/dummy/app/views/layers/custom/cascadingwms/auto/_cascaded_info.html.erb +6 -17
  20. data/test/dummy/app/views/layers/custom/cascadingwms/auto/_cascaded_legend.html.erb +2 -0
  21. data/test/dummy/app/views/layers/custom/cascadingwms/auto/_countries_info.html.erb +0 -11
  22. data/test/dummy/app/views/layers/custom/naturalearth/auto/_countries_info.html.erb +0 -11
  23. data/test/dummy/app/views/topics/_query_header.html.erb +3 -0
  24. data/test/dummy/app/views/topics/custom/auto/_cascadingwms_legend.html.erb +4 -0
  25. data/test/dummy/lib/assets/.gitkeep +0 -0
  26. data/test/dummy/lib/tasks/.gitkeep +0 -0
  27. data/test/dummy/lib/tasks/templates/_infotable_auto.html.erb +0 -11
  28. data/test/dummy/log/.gitkeep +0 -0
  29. data/test/dummy/mapconfig/maps.example.com/cascadingwms.map +4 -4
  30. data/test/dummy/public/apps/.sencha/workspace/plugin.xml +3 -0
  31. data/test/dummy/public/apps/.sencha/workspace/sencha.cfg +8 -0
  32. data/test/dummy/test/fixtures/.gitkeep +0 -0
  33. data/test/dummy/test/functional/.gitkeep +0 -0
  34. data/test/dummy/test/integration/.gitkeep +0 -0
  35. data/test/dummy/test/unit/.gitkeep +0 -0
  36. metadata +340 -336
  37. data/app/controllers/print_controller.rb~ +0 -243
  38. data/app/models/layer.rb~ +0 -283
  39. data/lib/tasks/mapfile.rake~ +0 -279
  40. data/test/dummy/config/database.yml +0 -52
  41. data/test/dummy/config/geodatabase.yml +0 -18
  42. data/test/dummy/log/development.log +0 -6378
  43. data/test/dummy/mapconfig/maps.example.com/connection.inc +0 -3
  44. data/test/dummy/tmp/cache/056/E21/permitted_resource_ids-index-Topic-roles-1 +0 -1
  45. data/test/dummy/tmp/cache/072/9A1/permitted_resource_ids-query-Layer-roles-1 +0 -0
  46. data/test/dummy/tmp/cache/0AB/111/permitted_resource_ids-legend-Layer-roles-1 +0 -0
  47. data/test/dummy/tmp/cache/FE2/C90/permitted_resource_ids-edit-Layer-roles-1 +0 -0
  48. data/test/dummy/tmp/cache/FE4/170/permitted_resource_ids-edit-Topic-roles-1 +0 -0
  49. data/test/dummy/tmp/cache/FF2/740/permitted_resource_ids-edit-Group-roles-1 +0 -0
  50. data/test/dummy/tmp/cache/FFD/960/permitted_resource_ids-show-Layer-roles-1 +0 -1
  51. data/test/dummy/tmp/cache/FFF/E40/permitted_resource_ids-show-Topic-roles-1 +0 -1
  52. data/test/dummy/tmp/pids/server.pid +0 -1
@@ -1,243 +0,0 @@
1
- #Mapfish print controller with access control and servlet call
2
-
3
- class PrintController < ApplicationController
4
- require 'popen4'
5
- begin
6
- require 'RMagick'
7
- rescue LoadError
8
- ActionController::Base.logger.info "Couldn't find RMagick. Image export not supported"
9
- end
10
-
11
- skip_before_filter :verify_authenticity_token, :only => :create # allow /print/create with POST
12
-
13
- caches_action :info
14
-
15
- class JavaError < Exception
16
- def initialize(cmd, message)
17
- super(cmd+"\n"+message)
18
- end
19
- end
20
-
21
- def initialize
22
- @configFile = "#{Rails.root}/config/print.yml"
23
- end
24
-
25
- TMP_PREFIX = "/opt/geodata/tmp/mfPrintTempFile" #WARNING: use NFS for multi-node setups! TODO: external config
26
- TMP_SUFFIX = ".pdf"
27
- TMP_PURGE_SECONDS = 600
28
-
29
- OUTPUT_FORMATS = ["pdf", "png", "jpg", "tif", "gif"]
30
-
31
- def info
32
- #if PRINT_URL.present?
33
- #TODO: call_servlet(request)
34
- cmd = baseCmd + " --clientConfig"
35
- result = ""
36
- errors = ""
37
- status = POpen4::popen4(cmd) do |stdout, stderr, stdin, pid|
38
-
39
- result = stdout.readlines.join("\n")
40
- errors = stderr.readlines.join("\n")
41
- end
42
- if status.nil? || status.exitstatus != 0
43
- raise JavaError.new(cmd, errors)
44
- else
45
- info = ActiveSupport::JSON.decode(result)
46
- info['createURL'] = url_for(:protocol => request.protocol, :action=>'create') + '.json'
47
- # add output formats
48
- info['outputFormats'] = []
49
- OUTPUT_FORMATS.each do |output_format|
50
- info['outputFormats'] << {:name => output_format}
51
- end
52
-
53
- respond_to do |format|
54
- format.json do
55
- if params[:var]
56
- render :text=>"var "+params[:var]+"="+result+";"
57
- else
58
- render :json=>info
59
- end
60
- end
61
- end
62
- end
63
- end
64
-
65
- def create
66
- cleanupTempFiles
67
-
68
- accessible_topics = Topic.accessible_by(current_ability).collect{ |topic| topic.name }
69
- layers_to_delete = []
70
- request.parameters["layers"].each do |layer|
71
- if layer["baseURL"] # WMS layers
72
- topic = File.basename(URI.parse(layer["baseURL"]).path)
73
- if accessible_topics.include?(topic)
74
- # rewrite URL for local WMS, use CGI if layer filter is used
75
- use_cgi = !layer["customParams"].nil? && layer["customParams"].any? { |param, value| param =~ LAYER_FILTER_REGEX }
76
- layer["baseURL"] = rewrite_wms_uri(layer["baseURL"], use_cgi)
77
- if layer["customParams"] #Set map_resolution for mapserver (MapFish print bug?)
78
- layer["customParams"].delete("DPI")
79
- layer["customParams"]["map_resolution"] = request.parameters["dpi"]
80
- end
81
- # For permission check in WMS controller: pass session as WMS request parameter
82
- #layer["customParams"]["session"] =
83
- else
84
- # collect inaccessible layers for later removal
85
- layers_to_delete << layer
86
- end
87
- end
88
-
89
- if layer["baseURL"].nil? && layer["styles"] #Vector layers
90
- layer["styles"].each_value do |style| #NoMethodError (undefined method `each_value' for [""]:Array):
91
- if style["externalGraphic"]
92
- style["externalGraphic"].gsub!(LOCAL_GRAPHICS_HOST, '127.0.0.1')
93
- style["externalGraphic"].gsub!(/^https:/, 'http:')
94
- end
95
- end
96
- end
97
- end
98
- # remove inaccessible layers
99
- request.parameters["layers"] -= layers_to_delete
100
-
101
- request.parameters["pages"].each do |page|
102
- # round center coordinates
103
- page["center"].collect! {|coord| (coord * 100.0).round / 100.0 }
104
- # add blank user strings if missing
105
- page["user_title"] = " " if page["user_title"].blank?
106
- page["user_comment"] = " " if page["user_comment"].blank?
107
- # base url
108
- page["base_url"] = "#{request.protocol}#{request.host}"
109
- # disclaimer
110
- topic = Topic.accessible_by(current_ability).where(:name => page["topic"]).first
111
- page["disclaimer"] = topic.nil? ? Topic.default_print_disclaimer : topic.print_disclaimer
112
- end
113
-
114
- logger.info request.parameters.to_yaml
115
-
116
- if PRINT_URL.present?
117
- call_servlet(request)
118
- else
119
- #print-standalone
120
- tempId = SecureRandom.random_number(2**31)
121
- temp = TMP_PREFIX + tempId.to_s + TMP_SUFFIX
122
- cmd = baseCmd + " --output=" + temp
123
- result = ""
124
- errors = ""
125
- status = POpen4::popen4(cmd) do |stdout, stderr, stdin, pid|
126
- stdin.puts request.parameters.to_json
127
- #body = request.body
128
- #FileUtils.copy_stream(body, stdin)
129
- #body.close
130
- stdin.close
131
- result = stdout.readlines.join("\n")
132
- errors = stderr.readlines.join("\n")
133
- end
134
- if status.nil? || status.exitstatus != 0
135
- raise JavaError.new(cmd, errors)
136
- else
137
- convert_and_send_link(temp, tempId, request.parameters["dpi"], request.parameters["outputFormat"])
138
- end
139
- end
140
- end
141
-
142
- def show
143
- output_format = params[:format]
144
- if OUTPUT_FORMATS.include?(output_format)
145
- temp = TMP_PREFIX + params[:id] + ".#{output_format}"
146
- case output_format
147
- when "pdf"
148
- type = 'application/x-pdf'
149
- when "png"
150
- type = 'image/png'
151
- when "jpg"
152
- type = 'image/jpeg'
153
- when "tif"
154
- type = 'image/tiff'
155
- when "gif"
156
- type = 'image/gif'
157
- end
158
- send_file temp, :type => type, :disposition => 'attachment', :filename => params[:id] + ".#{output_format}"
159
- end
160
- end
161
-
162
- protected
163
-
164
- def rewrite_wms_uri(url, use_cgi)
165
- #http://wms.zh.ch/basis -> http://127.0.0.1/cgi-bin/mapserv.fcgi?MAP=/opt/geodata/mapserver/maps/intranet/basis.map&
166
- out = url
167
- # get topic from layer URL
168
- uri = URI.parse(url)
169
- localwms = LOCAL_WMS.any? { |ref| uri.host =~ ref }
170
- if localwms
171
- topic = File.basename(uri.path)
172
- localhost = (@zone == ZONE_INTRANET) ? '127.0.0.1' : 'localhost'
173
- out = "http://#{localhost}#{use_cgi ? MAPSERV_CGI_URL : MAPSERV_URL}?MAP=#{MAPPATH}/#{@zone}/#{topic}.map&"
174
- #out = "http://#{localhost}:#{request.port}/wms/#{topic}"
175
- end
176
- out
177
- end
178
-
179
- def baseCmd
180
- "java -cp #{GbMapfishPrint::PRINT_JAR} org.mapfish.print.ShellMapPrinter --config=#{@configFile}"
181
- end
182
-
183
- def cleanupTempFiles
184
- minTime = Time.now - TMP_PURGE_SECONDS;
185
- OUTPUT_FORMATS.each do |output_format|
186
- Dir.glob(TMP_PREFIX + "*." + output_format).each do |path|
187
- if File.mtime(path) < minTime
188
- File.delete(path)
189
- end
190
- end
191
- end
192
- end
193
-
194
- def call_servlet(request)
195
- url = URI.parse(URI.decode(PRINT_URL))
196
- logger.info "Forward request: #{PRINT_URL}"
197
- printspec = request.parameters.to_json
198
-
199
- response = nil
200
- begin
201
- http = Net::HTTP.new(url.host, url.port)
202
- http.start do
203
- case request.method.to_s
204
- when 'GET' then response = http.get(url.path) #, request.headers
205
- #when 'POST' then response = http.post(url.path, printspec)
206
- when 'POST' then response = http.get("#{url.path}?spec=#{CGI.escape(printspec)}") #-> GET print.pdf
207
- else
208
- raise Exception.new("unsupported method `#{request.method}'.")
209
- end
210
- end
211
- rescue => err
212
- logger.info("#{err.class}: #{err.message}")
213
- render :nothing => true, :status => 500
214
- return
215
- end
216
- #send_data response.body, :status => response.code, :type=>'application/x-pdf', :disposition=>'attachment', :filename=>'map.pdf'
217
- tempId = SecureRandom.random_number(2**31)
218
- temp = TMP_PREFIX + tempId.to_s + TMP_SUFFIX
219
- File.open(temp, 'w') {|f| f.write(response.body) }
220
- convert_and_send_link(temp, tempId, request.parameters["dpi"], request.parameters["outputFormat"])
221
- end
222
-
223
- # optionally convert PDF to image and send link to print result
224
- def convert_and_send_link(temp_pdf, temp_id, dpi, output_format)
225
- temp_suffix = ".pdf"
226
-
227
- if output_format != "pdf" && OUTPUT_FORMATS.include?(output_format)
228
- # convert PDF to image
229
- pdf = Magick::Image.read(temp_pdf) { self.density = dpi }.first
230
- temp_suffix = ".#{output_format}"
231
- temp_img = TMP_PREFIX + temp_id.to_s + temp_suffix
232
- pdf.write(temp_img)
233
- File.delete(temp_pdf)
234
- end
235
-
236
- respond_to do |format|
237
- format.json do
238
- render :json=>{ 'getURL' => url_for(:action=>'show', :id=>temp_id) + temp_suffix }
239
- end
240
- end
241
- end
242
-
243
- end
@@ -1,283 +0,0 @@
1
- class Layer < ActiveRecord::Base
2
- has_many :topics_layers, :dependent => :destroy
3
- has_many :topics, :through => :topics_layers
4
- belongs_to :sublayer_group
5
-
6
- attr_protected []
7
-
8
- validates :name, :presence => true, :uniqueness => {:scope => :topic_name}
9
- validates_format_of :name, :with => /\A[A-Za-z][\w-]*\Z/
10
- validates_format_of :topic_name, :with => /\A[\w-]+\Z/
11
-
12
- scope :defaultorder, order(:topic_name, :name)
13
- scope :unused, includes(:topics_layers).where('topics_layers.layer_id IS NULL')
14
-
15
- #Namespace for run-time geo classes
16
- module Geo
17
- end
18
-
19
- # Enum for RailsAdmin form (causes exception in name search)
20
- #def sublayer_group_enum
21
- # SublayerGroup.all.collect {|p| [ p.name, p.id ] }
22
- #end
23
-
24
- #Structure for Topic selection
25
- def self.list(ability, layer_type, topic_name)
26
- topic = Topic.accessible_by(ability).includes(:layers).where(:name => topic_name).first
27
- layers = topic.nil? ? [] : topic.layers.accessible_by(ability).all
28
- topic_layers = topic.nil? ? [] : topic.topics_layers.select {|tl| layers.include?(tl.layer) }
29
- wms_layer_list(ability, topic, topic_layers)
30
- end
31
-
32
- def self.wms_layer_list(ability, topic, topic_layers)
33
- wms_layers = topic_layers.collect do |topic_layer|
34
- layer = topic_layer.layer
35
- {
36
- "id" => topic_layer.id,
37
- "layername"=> layer.name,
38
- "topic"=> topic.name,
39
- "groupname" => layer.sublayer_group.try(:name),
40
- "toclayertitle"=> layer.title,
41
- "leglayertitle"=> layer.title,
42
- "showscale"=> "true",
43
- "minscale"=> layer.minscale,
44
- "maxscale"=> layer.maxscale,
45
- "wms_sort"=> topic_layer.wms_sort, # MapServer layer order
46
- #"leg_sort"=> topic_layer.leg_sort, # Not used client side (Legend sort is in defined in HTML). Query result order.
47
- #"query_sort"=> topic_layer.leg_sort, # deprecated
48
- "toc_sort"=> topic_layer.toc_sort, # Layer tree order
49
- "wms"=> "false",
50
- "visini"=> topic_layer.visini,
51
- "visuser"=> topic_layer.visini, #User visibility is in request_state
52
- "showtoc"=> "true",
53
- "editeable"=> ability.can?(:edit, layer)
54
- }
55
- end
56
- {
57
- "success" => true,
58
- "messageProperty"=> {"topic"=> topic.name, "legendtitle"=> "Legende", "legendraster"=> "true"},
59
- "results"=> wms_layers.size,
60
- "wmslayers"=> wms_layers
61
- }
62
- end
63
-
64
- def full_name
65
- "#{topic_name}-#{name}".downcase
66
- end
67
-
68
- def feature_class
69
- fc = "Geo::#{feature_class_name}".constantize rescue nil #Geo.const_defined?(feature_class_name) seems not to work here
70
- fc ||= Geo.module_eval <<EOS
71
- class #{feature_class_name} < GeoModel
72
- self.table_name = '#{table}'
73
- self.primary_key = '#{pkey}'
74
-
75
- self
76
- end
77
- EOS
78
- end
79
-
80
- def feature_class_name
81
- table.camelize.singularize
82
- end
83
-
84
- def geometry_column
85
- feature_class.try(:geometry_column)
86
- end
87
-
88
- def attribute(name)
89
- if feature_class.nil?
90
- ::Attribute.new(self, name)
91
- else
92
- @attrs ||= feature_class.columns.inject({}) do |h, c|
93
- #logger.info "************************* feature_class column c #{c.inspect}"
94
- h[c.name] = ::Attribute.new(self, c.name)
95
- h
96
- end
97
- @attrs[name] ||= ::Attribute.new(self, name) #Add ad-hoc Attr. for calculated columns (e.g. custom SQL in query fields)
98
- end
99
- #logger.info "************************* Attribute for name '#{name}': #{@attrs[name].inspect}"
100
- end
101
-
102
- #def filtered(ability)
103
- # feature_class.where(ability.resource_access_filter(self))
104
- #end
105
-
106
- def query_fields(ability)
107
- return '' if feature_class.nil?
108
- area_field = "ST_Area(#{geometry_column.name}) AS area"
109
- #TODO: measure -> Measure(geometry_column, lat, lon)
110
- ([pkey]+ident_fields_for(ability)+[feature_class.extent_field, area_field]).join(',')
111
- end
112
-
113
- def ident_fields_for(ability)
114
- #attributes.accessible_by(ability) & fields
115
- #logger.info "************************* fields layer #{name}: #{ident_fields}"
116
- #logger.info "************************* roles: #{ability.roles.collect(&:name).join(',')}"
117
- allowed_fields = ident_fields.split(',').select { |f| ability.can?(:show, attribute(f)) }
118
- #logger.info "************************* ident_fields layer #{name}: #{allowed_fields.inspect}"
119
- allowed_fields
120
- end
121
-
122
- def query(ability, query_topic, searchbbox)
123
- if feature_class
124
- begin
125
- #query_topic: {... customQueries: {<layername>: <query_method> }
126
- #e.g.
127
- #{"queryTopics":[{
128
- # "level":"main","topic":"Lageklassen2011ZH","divCls":"legmain","layers":"seen,lageklassen-2011-flaechen,grenzen,gemeindegrenzen,bezirkslabels"
129
- # customQueries: {'seen': 'tiefen_statistik'},
130
- # customParams: {'tiefe': 25}
131
- # }]}
132
- custom_query_method = query_topic['customQueries'][name] rescue nil
133
- logger.debug "******** #{feature_class} ***************************************************"
134
- features = if custom_query_method
135
- logger.debug "Custom query on layer #{name}: #{query_topic.inspect}"
136
- feature_class.send(custom_query_method, self, query_topic, searchbbox)
137
- else
138
- logger.debug "Identify on layer #{name} with query fields #{query_fields(ability)} at #{searchbbox.inspect}"
139
- feature_class.identify_filter(searchbbox, searchdistance).select(query_fields(ability)).all
140
- end
141
- logger.debug "Number of features: #{features.size}"
142
- # calculate bbox of all features
143
- unless features.empty?
144
- envelope = GeoRuby::SimpleFeatures::Geometry.from_hex_ewkb(features.first['extent']).envelope
145
- features.each do |feature|
146
- next if feature == features.first
147
- envelope.extend!(GeoRuby::SimpleFeatures::Geometry.from_hex_ewkb(feature['extent']).envelope)
148
- end
149
- bbox = [envelope.lower_corner.x, envelope.lower_corner.y, envelope.upper_corner.x, envelope.upper_corner.y]
150
- end
151
- rescue Exception => e
152
- features = "Table: <b>#{table}</b><br/>Exception: #{e}<br/>query fields: #{query_fields(ability)}<br/>db fields: #{feature_class.column_names.join(',')}<br/>missing: <font color='red'>#{(query_fields(ability).split(',') - feature_class.column_names).join(', ')}</font><br/><br/>"
153
- logger.info "Identfy error on layer #{name} #{features}"
154
- end
155
- [self, features, bbox]
156
- else
157
- logger.warn "Table for layer #{name} not found. (Table name: '#{table}')"
158
- nil
159
- end
160
- end
161
-
162
- # Partial for identify result
163
- def info_fname
164
- "_#{name}_info.html.erb"
165
- end
166
-
167
- def info_file
168
- File.join(Rails.root, 'app', 'views', 'layers', 'custom', topic_name.downcase, info_fname)
169
- end
170
-
171
- def info_file_auto
172
- File.join(Rails.root, 'app', 'views', 'layers', 'custom', topic_name.downcase, 'auto', info_fname)
173
- end
174
-
175
- # ignore auto file if empty file exists
176
- def info_file_empty
177
- File.join(Rails.root, 'app', 'views', 'layers', 'custom', topic_name.downcase, "_#{name}_info_leer.html.erb")
178
- end
179
-
180
- def info
181
- @info ||= begin
182
- if File.exist?(info_file)
183
- "layers/custom/#{topic_name.downcase}/#{info_fname[1..-10]}"
184
- elsif !File.exist?(info_file_empty) && File.exist?(info_file_auto)
185
- "layers/custom/#{topic_name.downcase}/auto/#{info_fname[1..-10]}"
186
- else
187
- nil
188
- end
189
- end
190
- end
191
-
192
- def infotext(count)
193
- count > 0 ? "resultcount_p" : "resultcount_s"
194
- end
195
-
196
- def infotab
197
- # INFOLAYOUT=0^1^2^3^4^5^6^7 *** Wenn der Parameter = 1 ist, wird ein leerer String �bergeben.
198
- # *** Wenn der Parameter = 0 ist, wird der entsprechende Teil weggelassen wenn m�glich
199
- #
200
- # LayoutString(0) = "Im Umkreis von <EM>xUmkreisx</EM> Meter(n) wurde <EM>xAnzahlx</EM> Datensatz gefunden.<br><br>"
201
- # LayoutString(1) = "Im Umkreis von <EM>xUmkreisx</EM> Meter(n) wurden <EM>xAnzahlx</EM> Datens&aumltze gefunden.<br><br>"
202
- # LayoutString(2) = "layer"
203
- # LayoutString(3) = "infotext"
204
- # LayoutString(4) = "infotab"
205
- # LayoutString(5) = "tabtitle"
206
- # LayoutString(6) = "tabcell"
207
- # LayoutString(7) = "2" ( If = "" Then 1 Tabellenzeile pro Record [z.B. "1" oder ""], else [z.B. "2"] 1 Zeile pro Feld)
208
-
209
- "infotable_horizontal"
210
- end
211
-
212
- def legend_fname
213
- "_#{name}_legend.html.erb"
214
- end
215
-
216
- def legend_file
217
- File.join(Rails.root, 'app', 'views', 'layers', 'custom', topic_name.downcase, legend_fname)
218
- end
219
-
220
- def legend_file_auto
221
- File.join(Rails.root, 'app', 'views', 'layers', 'custom', topic_name.downcase, 'auto', legend_fname)
222
- end
223
-
224
- def legend
225
- @legend ||= begin
226
- if File.exist?(legend_file)
227
- "layers/custom/#{topic_name.downcase}/#{legend_fname[1..-10]}"
228
- elsif File.exist?(legend_file_auto)
229
- "layers/custom/#{topic_name.downcase}/auto/#{legend_fname[1..-10]}"
230
- else
231
- nil
232
- end
233
- end
234
- end
235
-
236
- def quoted_wms_layers
237
- wms_layers.split(',').collect {|l| %Q<"#{l}"> }.join(',')
238
- end
239
-
240
- DEFAULT_SELECTION_STYLE = {
241
- 'POLYGON' =>
242
- '<PolygonSymbolizer>'+
243
- '<Fill>'+
244
- '<CssParameter name="fill">#ff0090</CssParameter>'+
245
- '<CssParameter name="fill-opacity">0.6</CssParameter>'+
246
- '</Fill>'+
247
- '<Stroke>'+
248
- '<CssParameter name="stroke">#ff0090</CssParameter>'+
249
- '<CssParameter name="stroke-width">2.00</CssParameter>'+
250
- '</Stroke>'+
251
- '</PolygonSymbolizer>',
252
- 'LINESTRING' =>
253
- '<LineSymbolizer>'+
254
- '<Stroke>'+
255
- '<CssParameter name="stroke">#ff0090</CssParameter>'+
256
- '<CssParameter name="stroke-width">10.00</CssParameter>'+
257
- '</Stroke>'+
258
- '</LineSymbolizer>',
259
- 'POINT' =>
260
- '<PointSymbolizer>'+
261
- '<Graphic>'+
262
- '<Mark>'+
263
- '<WellKnownName>circle</WellKnownName>'+
264
- '<Fill>'+
265
- '<CssParameter name="fill">#ff0090</CssParameter>'+
266
- '</Fill>'+
267
- '</Mark>'+
268
- '<Size>45.0</Size>'+
269
- '</Graphic>'+
270
- '</PointSymbolizer>'
271
- }
272
-
273
- def selection_symbolizer
274
- if selection_style.blank?
275
- gtyp = feature_class.geometry_type.sub(/^MULTI/, '').sub(/M$/, '') #MULTIPOINTM -> POINT
276
- logger.error "Unsupported selection geometry type #{feature_class.geometry_type}" unless DEFAULT_SELECTION_STYLE.has_key?(gtyp)
277
- DEFAULT_SELECTION_STYLE[gtyp] || ''
278
- else
279
- selection_style
280
- end
281
- end
282
-
283
- end