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.
@@ -25,12 +25,21 @@ class RegistrationsController < Devise::RegistrationsController
25
25
  super
26
26
  end
27
27
 
28
+ # show confirmation for registration of existing users
29
+ def confirm
30
+ end
31
+
28
32
  def login
29
33
  # redirected to here after AJAX login
30
34
  if user_signed_in?
31
35
  render :json => {
32
36
  :success => true,
33
- :user => { :login => current_user.login, :email => current_user.email},
37
+ :user => {
38
+ :login => current_user.login,
39
+ :email => current_user.email,
40
+ :name => current_user.name,
41
+ :app_infos => current_user.app_infos
42
+ },
34
43
  :roles => current_roles.roles.collect(&:name)
35
44
  }
36
45
  else
@@ -53,4 +62,4 @@ class RegistrationsController < Devise::RegistrationsController
53
62
  def application_layout
54
63
  params[:layout] || "application"
55
64
  end
56
- end
65
+ end
@@ -37,9 +37,60 @@ class TopicsController < ApplicationController
37
37
  topic = Topic.where(:name => query_topic['topic']).first
38
38
  authorize! :show, topic
39
39
  query_topic['topicobj'] = topic
40
- query_topic['results'] = topic.query(current_ability, query_topic, params['bbox'])
40
+ if params['bbox']
41
+ query_topic['results'] = topic.query(current_ability, query_topic, params['bbox'])
42
+ elsif params['rect']
43
+ x1, y1, x2, y2 = params['rect'].split(',').collect(&:to_f)
44
+ rect = "POLYGON((#{x1} #{y1}, #{x1} #{y2}, #{x2} #{y2}, #{x2} #{y1} ,#{x1} #{y1}))"
45
+ query_topic['results'] = topic.query(current_ability, query_topic, rect)
46
+ elsif params['circle']
47
+ query_topic['results'] = topic.query(current_ability, query_topic, params['circle'])
48
+ elsif params['poly']
49
+ query_topic['results'] = topic.query(current_ability, query_topic, params['poly'])
50
+ else
51
+ # problem
52
+ end
41
53
  end
42
- render :layout => false
54
+ if params['bbox']
55
+ x1, y1, x2, y2 = (params['bbox']).split(',').collect(&:to_f)
56
+ @xx = (x1 + x2) / 2.0
57
+ @yy = (y1 + y2) / 2.0
58
+ @height = Dtm.getHeight(params['bbox'])
59
+ else
60
+ @xx = 0
61
+ @yy = 0
62
+ @height = 0
63
+ end
64
+
65
+ respond_to do |format|
66
+ format.html { render :layout => false }
67
+
68
+ format.json do
69
+ render :json => prepJson
70
+ end
71
+ format.jsonp do
72
+ render :json => prepJson, :callback => params[:callback]
73
+ end
74
+ end
75
+ end
76
+
77
+ def prepJson
78
+ query_results = {}
79
+ @query_topics.each do |query_topic|
80
+ layer_results = {}
81
+ query_topic['results'].each do |result|
82
+ layer_results[result[0][:name]] = result
83
+ end
84
+ query_results[query_topic['topicobj'].name] = layer_results
85
+ end
86
+
87
+ {
88
+ :results => query_results,
89
+ :height => @height,
90
+ :x => @xx,
91
+ :y => @yy
92
+ }.to_json
93
+
43
94
  end
44
95
 
45
96
  def legend
@@ -0,0 +1,133 @@
1
+ class TopicsController < ApplicationController
2
+
3
+ #cache topics.json
4
+ caches_action :index, :cache_path => Proc.new {
5
+ {:ssl => request.ssl?, :app => params[:gbapp], :roles => current_roles.roles}
6
+ }
7
+
8
+ def index
9
+ @app = Gbapplication.find_by_name(params[:gbapp]) if params[:gbapp]
10
+ if @app.nil?
11
+ logger.error "Gbapplication '#{params[:gbapp]}' not found"
12
+ head :bad_request
13
+ return
14
+ end
15
+
16
+ respond_to do |format|
17
+ format.json do
18
+ render :json => Topic.list(@app, current_ability, host_zone(request.host), wms_host)
19
+ end
20
+ end
21
+ end
22
+
23
+ def show #TODO: obsolete?
24
+ @topic = Topic.includes(:layers).find(params[:id])
25
+
26
+ respond_to do |format|
27
+ format.json do
28
+ render :json => @topic.to_json(:include => :layers)
29
+ end
30
+ end
31
+ end
32
+
33
+ =begin
34
+ def query0
35
+ @query_topics = ActiveSupport::JSON.decode(params[:infoQuery])['queryTopics']
36
+ #e.g. [{"layers"=>"lk25,grenzen,gemeindegrenzen,seen,wald,haltestellen", "divCls"=>"legmain", "level"=>"main", "topic"=>"BASISKARTEZH"}, {"layers"=>"", "divCls"=>"legover", "level"=>"over", "topic"=>"AVParzOverlayZH"}]
37
+ @query_topics.each do |query_topic|
38
+ topic = Topic.where(:name => query_topic['topic']).first
39
+ authorize! :show, topic
40
+ query_topic['topicobj'] = topic
41
+ query_topic['results'] = topic.query(current_ability, query_topic, params['bbox'])
42
+ end
43
+ x1, y1, x2, y2 = (params['bbox']).split(',').collect(&:to_f)
44
+ @xx = (x1 + x2) / 2.0
45
+ @yy = (y1 + y2) / 2.0
46
+ @height = Dtm.getHeight(params['bbox'])
47
+
48
+
49
+ respond_to do |format|
50
+ format.html { render :layout => false }
51
+
52
+ format.json do
53
+ render :json => prepJson
54
+ end
55
+ format.jsonp do
56
+ render :json => prepJson, :callback => params[:callback]
57
+ end
58
+ end
59
+ end
60
+ =end
61
+
62
+ def query
63
+ @query_topics = ActiveSupport::JSON.decode(params[:infoQuery])['queryTopics']
64
+ #e.g. [{"layers"=>"lk25,grenzen,gemeindegrenzen,seen,wald,haltestellen", "divCls"=>"legmain", "level"=>"main", "topic"=>"BASISKARTEZH"}, {"layers"=>"", "divCls"=>"legover", "level"=>"over", "topic"=>"AVParzOverlayZH"}]
65
+ @query_topics.each do |query_topic|
66
+ topic = Topic.where(:name => query_topic['topic']).first
67
+ authorize! :show, topic
68
+ query_topic['topicobj'] = topic
69
+ if params['bbox']
70
+ query_topic['results'] = topic.query(current_ability, query_topic, params['bbox'])
71
+ elsif params['rect']
72
+ x1, y1, x2, y2 = params['rect'].split(',').collect(&:to_f)
73
+ rect = "POLYGON((#{x1} #{y1}, #{x1} #{y2}, #{x2} #{y2}, #{x2} #{y1} ,#{x1} #{y1}))"
74
+ query_topic['results'] = topic.query(current_ability, query_topic, rect)
75
+ elsif params['circle']
76
+ query_topic['results'] = topic.query(current_ability, query_topic, params['circle'])
77
+ elsif params['poly']
78
+ query_topic['results'] = topic.query(current_ability, query_topic, params['poly'])
79
+ else
80
+ # problem
81
+ end
82
+ end
83
+ if params['bbox']
84
+ x1, y1, x2, y2 = (params['bbox']).split(',').collect(&:to_f)
85
+ @xx = (x1 + x2) / 2.0
86
+ @yy = (y1 + y2) / 2.0
87
+ @height = Dtm.getHeight(params['bbox'])
88
+ else
89
+ @xx = 0
90
+ @yy = 0
91
+ @height = 0
92
+ end
93
+
94
+ respond_to do |format|
95
+ format.html { render :layout => false }
96
+
97
+ format.json do
98
+ render :json => prepJson
99
+ end
100
+ format.jsonp do
101
+ render :json => prepJson, :callback => params[:callback]
102
+ end
103
+ end
104
+ end
105
+
106
+ def prepJson
107
+ query_results = {}
108
+ @query_topics.each do |query_topic|
109
+ layer_results = {}
110
+ query_topic['results'].each do |result|
111
+ layer_results[result[0][:name]] = result
112
+ end
113
+ query_results[query_topic['topicobj'].name] = layer_results
114
+ end
115
+
116
+ {
117
+ :results => query_results,
118
+ :height => @height,
119
+ :x => @xx,
120
+ :y => @yy
121
+ }.to_json
122
+
123
+ end
124
+
125
+ def legend
126
+ #TODO: -> show?mode=legend
127
+ @topic = Topic.includes(:layers).where(:name => params[:id]).first
128
+ @topic ||= Topic.includes(:layers).find(params[:id])
129
+ authorize! :show, @topic
130
+ render :layout => false
131
+ end
132
+
133
+ end
@@ -4,7 +4,7 @@ require 'uri'
4
4
  class WmsController < ApplicationController
5
5
 
6
6
  def show
7
- logger.info "----> WMS call with user '#{current_user.try(:login)}'"
7
+ logger.debug "----> WMS call with user '#{current_user.try(:login)}'"
8
8
 
9
9
  topic = Topic.where(:name => params[:service]).first
10
10
  add_sld_body(topic)
@@ -108,15 +108,26 @@ class Ability
108
108
  end
109
109
  else
110
110
  if layer == '*'
111
- #resource_object.topics.detect { |t| t.name == topic }
112
- resource_object.topics.where(:name => topic)
111
+ layer_topics_lookup[resource_object.id].include?(topic)
113
112
  else
114
- #resource_object.name == layer && resource_object.topics.detect { |t| t.name == topic }
115
- resource_object.name == layer && resource_object.topics.where(:name => topic)
113
+ resource_object.name == layer && layer_topics_lookup[resource_object.id].include?(topic)
116
114
  end
117
115
  end
118
116
  end
119
117
 
118
+ private
119
+
120
+ def layer_topics_lookup
121
+ #Build a lookup hash for all layer -> topic relations
122
+ @layer_topics ||= begin
123
+ layer_topics = resources.all.inject({}) {|hsh,l| hsh[l.id] = []; hsh }
124
+ # layer_topics = resources.inject({}) {|hsh,l| hsh[l.id] = []; hsh }
125
+ all_topics = Topic.select("topics.id,topics.name,layers.id,layers.name").includes(:layers)
126
+ all_topics.each {|t| t.layers.each {|l| layer_topics[l.id] << t.name} }
127
+ layer_topics
128
+ end
129
+ end
130
+
120
131
  end
121
132
 
122
133
  # ----------
@@ -265,8 +276,6 @@ class Ability
265
276
  else
266
277
  #can :change_password, User, _id => @user.id #TODO: allow edit password
267
278
 
268
- Rails.logger.info "Loading permissions for roles #{roles.collect(&:name).join('+')}"
269
-
270
279
  #Topic permissions
271
280
  TopicResourceType.new.add_ability(self, roles)
272
281
 
@@ -34,12 +34,35 @@ class GeoModel < ActiveRecord::Base
34
34
  "ST_Envelope(#{table_name}.#{geometry_column_name}) AS extent"
35
35
  end
36
36
 
37
- def self.identify_filter(bbox, radius)
38
- x1, y1, x2, y2 = bbox.split(',').collect(&:to_f)
39
- center = "ST_GeomFromText('POINT(#{x1+(x2-x1)/2} #{y1+(y2-y1)/2})', #{srid})"
40
- scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{center}, #{radius})")
37
+ def self.area_field
38
+ "ST_Area(#{table_name}.#{geometry_column.name}) AS area"
41
39
  end
42
40
 
41
+ def self.identify_filter(searchgeo, radius)
42
+ if searchgeo[0..3] == "POLY"
43
+ logger.debug "*** POLY-query: #{searchgeo} ***"
44
+ polygon = "ST_GeomFromText('#{searchgeo}', #{srid})"
45
+ scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{polygon}, #{radius})")
46
+ else
47
+ if searchgeo.split(',').length == 3
48
+ logger.debug "*** CIRCLE-query: #{searchgeo} ***"
49
+ x1, y1, r = searchgeo.split(',').collect(&:to_f)
50
+ center = "ST_GeomFromText('POINT(#{x1} #{y1})', #{srid})"
51
+ scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{center}, #{r})")
52
+ else
53
+ logger.debug "*** BBOX-query: #{searchgeo} ***"
54
+ x1, y1, x2, y2 = searchgeo.split(',').collect(&:to_f)
55
+ center = "ST_GeomFromText('POINT(#{x1+(x2-x1)/2} #{y1+(y2-y1)/2})', #{srid})"
56
+ scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{center}, #{radius})")
57
+ end
58
+ end
59
+ end
60
+
61
+ #Custom identify query
62
+ #def self.identify_query(bbox, radius)
63
+ # scoped.select().where()....
64
+ #end
65
+
43
66
  def bbox
44
67
  envelope = GeoRuby::SimpleFeatures::Geometry.from_hex_ewkb(extent).envelope #TODO: replace with rgeo
45
68
  [envelope.lower_corner.x, envelope.lower_corner.y, envelope.upper_corner.x, envelope.upper_corner.y]
@@ -0,0 +1,183 @@
1
+ class GeoModel < ActiveRecord::Base
2
+ establish_connection(GEODB)
3
+
4
+ self.abstract_class = true
5
+
6
+ attr_protected []
7
+
8
+ def self.geometry_column_info
9
+ #spatial_column_info returns key/value list with geometry_column name as key
10
+ #value example: {:srid=>21781, :type=>"MULTIPOLYGON", :dimension=>2, :has_z=>false, :has_m=>false, :name=>"the_geom"}
11
+ #We take the first matching entry
12
+ @geometry_column_info ||= connection.spatial_column_info(table_name).values.first
13
+ end
14
+
15
+ def self.geometry_column_name
16
+ geometry_column_info[:name]
17
+ end
18
+
19
+ def self.geometry_type
20
+ geometry_column_info[:type]
21
+ end
22
+
23
+ def self.srid
24
+ geometry_column_info[:srid]
25
+ end
26
+
27
+ def self.geometry_column
28
+ col = columns_hash[geometry_column_name]
29
+ col.instance_eval { @srid = srid }
30
+ col
31
+ end
32
+
33
+ def self.extent_field
34
+ "ST_Envelope(#{table_name}.#{geometry_column_name}) AS extent"
35
+ end
36
+
37
+ def self.area_field
38
+ "ST_Area(#{table_name}.#{geometry_column.name}) AS area"
39
+ end
40
+
41
+ def self.identify_filter(searchgeo, radius)
42
+ if searchgeo[0..3] == "POLY"
43
+ logger.debug "*** POLY-query: #{searchgeo} ***"
44
+ polygon = "ST_GeomFromText('#{searchgeo}', #{srid})"
45
+ scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{polygon}, #{radius})")
46
+ # self.identify_filter_polygon(searchgeo, radius)
47
+ else
48
+ if searchgeo.split(',').length == 3
49
+ logger.debug "*** CIRCLE-query: #{searchgeo} ***"
50
+ x1, y1, r = searchgeo.split(',').collect(&:to_f)
51
+ center = "ST_GeomFromText('POINT(#{x1} #{y1})', #{srid})"
52
+ scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{center}, #{r})")
53
+ else
54
+ logger.debug "*** BBOX-query: #{searchgeo} ***"
55
+ x1, y1, x2, y2 = searchgeo.split(',').collect(&:to_f)
56
+ center = "ST_GeomFromText('POINT(#{x1+(x2-x1)/2} #{y1+(y2-y1)/2})', #{srid})"
57
+ scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{center}, #{radius})")
58
+ end
59
+ end
60
+ end
61
+
62
+ #Custom identify query
63
+ #def self.identify_query(bbox, radius)
64
+ # scoped.select().where()....
65
+ #end
66
+
67
+ def bbox
68
+ envelope = GeoRuby::SimpleFeatures::Geometry.from_hex_ewkb(extent).envelope #TODO: replace with rgeo
69
+ [envelope.lower_corner.x, envelope.lower_corner.y, envelope.upper_corner.x, envelope.upper_corner.y]
70
+ end
71
+
72
+ # based on mapfish_filter
73
+ def self.bbox_filter(params)
74
+ filter = scoped
75
+
76
+ if params['bbox']
77
+ x1, y1, x2, y2 = params['bbox'].split(',').collect(&:to_f)
78
+ box = [[x1, y1], [x2, y2]]
79
+ filter_geom = "'BOX3D(#{box[0].join(" ")},#{box[1].join(" ")})'::box3d"
80
+ elsif params['polygon']
81
+ filter_geom = "ST_GeomFromText('#{params['polygon']}')"
82
+ end
83
+
84
+ if filter_geom
85
+ filter = filter.where("ST_Intersects(#{table_name}.#{connection.quote_column_name(geometry_column_name)}, ST_SetSRID(#{filter_geom}, #{srid}))")
86
+ end
87
+
88
+ filter
89
+ end
90
+
91
+ def self.geojson_decode(json)
92
+ RGeo::GeoJSON.decode(json, :json_parser => :json, :geo_factory => geo_factory)
93
+ end
94
+
95
+ def to_geojson(options = {})
96
+ only = options.delete(:only)
97
+ geoson = { :type => 'Feature' }
98
+ geoson[:properties] = attributes.delete_if do |name, value|
99
+ # TODO: support for multiple geometry columns
100
+ if name == self.class.geometry_column_name
101
+ geoson[:geometry] = value
102
+ true
103
+ elsif name == self.class.primary_key then
104
+ geoson[:id] = value
105
+ true
106
+ elsif only
107
+ !only.include?(name.to_sym)
108
+ end
109
+ end
110
+ geoson.to_json
111
+ end
112
+
113
+ def update_attributes_from_geojson_feature(feature, user)
114
+ attr = feature.properties
115
+ attr[self.class.geometry_column_name] = feature.geometry
116
+ ok = update_attributes(attr)
117
+ modified_by(user)
118
+ ok
119
+ end
120
+
121
+ # update modification attributes (changed_by, etc.)
122
+ # Override in descendant classes
123
+ def modified_by(user)
124
+ #none by default
125
+ end
126
+
127
+ def self.can_edit?(ability)
128
+ @@layers ||= Layer.where(:table => self.table_name).all
129
+ can_edit = false
130
+ @@layers.each do |layer|
131
+ # check if any layer with this table is editable
132
+ if ability.can?(:edit, layer)
133
+ can_edit = true
134
+ break
135
+ end
136
+ end
137
+ can_edit
138
+ end
139
+
140
+ # apply user filter for editing
141
+ # Override in descendant classes
142
+ def self.user_filter(ability)
143
+ if ability.nil?
144
+ forbidden(ability)
145
+ elsif can_edit?(ability)
146
+ scoped #No filter
147
+ else
148
+ forbidden(ability)
149
+ end
150
+ end
151
+
152
+ def self.forbidden(ability)
153
+ if ability.nil?
154
+ logger.info "----> Edit access forbidden without login"
155
+ else
156
+ logger.info "----> Edit access forbidden with roles #{ability.roles.collect(&:name).join('+')}!"
157
+ end
158
+ where('1=0') # No access
159
+ end
160
+
161
+ # header for CSV export
162
+ def csv_header
163
+ #empty by default
164
+ []
165
+ end
166
+
167
+ # row values for CSV export
168
+ def csv_row
169
+ #empty by default
170
+ []
171
+ end
172
+
173
+ def self.geo_factory
174
+ if self.rgeo_factory_generator == RGeo::ActiveRecord::DEFAULT_FACTORY_GENERATOR
175
+ self.rgeo_factory_generator = RGeo::Geos.factory_generator
176
+ rgeo_factory_settings.set_column_factory(table_name, geometry_column_name,
177
+ RGeo::Cartesian.factory(:srid => 21781, :proj4 => '+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 +x_0=600000 +y_0=200000 +ellps=bessel +towgs84=674.4,15.1,405.3,0,0,0,0 +units=m +no_defs')
178
+ )
179
+ end
180
+ rgeo_factory_for_column(geometry_column_name)
181
+ end
182
+
183
+ end