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.
- data/app/controllers/apps_controller.rb +9 -1
- data/app/controllers/apps_controller.rb~ +66 -0
- data/app/controllers/groups_users_controller.rb +73 -14
- data/app/controllers/print_controller.rb +97 -5
- data/app/controllers/print_controller.rb~ +95 -3
- data/app/controllers/registrations_controller.rb +11 -2
- data/app/controllers/topics_controller.rb +53 -2
- data/app/controllers/topics_controller.rb~ +133 -0
- data/app/controllers/wms_controller.rb +1 -1
- data/app/models/ability.rb +15 -6
- data/app/models/geo_model.rb +27 -4
- data/app/models/geo_model.rb~ +183 -0
- data/app/models/layer.rb +18 -14
- data/app/models/permission.rb +22 -18
- data/app/models/search_model.rb +5 -2
- data/app/models/tool.rb +1 -1
- data/app/models/topic.rb +46 -44
- data/app/models/topic.rb~ +182 -0
- data/app/models/user.rb +13 -1
- data/app/views/devise/mailer/reset_password_instructions.html.erb +11 -4
- data/app/views/groups_users/mails/_default.html.erb +3 -0
- data/app/views/registrations/confirm.html.erb +6 -0
- data/app/views/registrations/edit.html.erb +0 -9
- data/app/views/registrations/new.html.erb +17 -1
- data/lib/gb_mapfish_appserver/engine.rb +2 -0
- data/lib/gb_mapfish_appserver/version.rb +1 -1
- data/lib/generators/mapfish/install/templates/initializer.rb +6 -0
- data/lib/tasks/mapfile.rake +2 -2
- metadata +4475 -4476
- data/app/models/layer.rb~ +0 -283
data/app/models/layer.rb~
DELETED
@@ -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ätze 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
|