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