gb_mapfish_appserver 0.0.3 → 0.0.4

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.
@@ -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