gb_mapfish_appserver 0.0.3 → 0.0.4

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