Class: GeoModel
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- GeoModel
- Defined in:
- app/models/geo_model.rb
Direct Known Subclasses
Class Method Summary collapse
- .area_field ⇒ Object
-
.bbox_filter(params) ⇒ Object
based on mapfish_filter.
- .can_edit?(ability) ⇒ Boolean
- .extent_field ⇒ Object
- .forbidden(ability) ⇒ Object
- .geo_factory ⇒ Object
- .geojson_decode(json) ⇒ Object
- .geometry_column ⇒ Object
- .geometry_column_info ⇒ Object
- .geometry_column_name ⇒ Object
- .geometry_type ⇒ Object
- .identify_filter(searchgeo, radius) ⇒ Object
- .srid ⇒ Object
-
.user_filter(ability) ⇒ Object
apply user filter for editing Override in descendant classes.
Instance Method Summary collapse
-
#bbox ⇒ Object
Custom identify query def self.identify_query(bbox, radius) scoped.select().where().…
-
#csv_header ⇒ Object
header for CSV export.
-
#csv_row ⇒ Object
row values for CSV export.
-
#modified_by(user) ⇒ Object
update modification attributes (changed_by, etc.) Override in descendant classes.
- #to_geojson(options = {}) ⇒ Object
- #update_attributes_from_geojson_feature(feature, user) ⇒ Object
Class Method Details
.area_field ⇒ Object
37 38 39 |
# File 'app/models/geo_model.rb', line 37 def self.area_field "ST_Area(#{table_name}.#{geometry_column.name}) AS area" end |
.bbox_filter(params) ⇒ Object
based on mapfish_filter
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'app/models/geo_model.rb', line 72 def self.bbox_filter(params) filter = scoped if params['bbox'] x1, y1, x2, y2 = params['bbox'].split(',').collect(&:to_f) box = [[x1, y1], [x2, y2]] filter_geom = "'BOX3D(#{box[0].join(" ")},#{box[1].join(" ")})'::box3d" elsif params['polygon'] filter_geom = "ST_GeomFromText('#{params['polygon']}')" end if filter_geom filter = filter.where("ST_Intersects(#{table_name}.#{connection.quote_column_name(geometry_column_name)}, ST_SetSRID(#{filter_geom}, #{srid}))") end filter end |
.can_edit?(ability) ⇒ Boolean
126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'app/models/geo_model.rb', line 126 def self.can_edit?(ability) @@layers ||= Layer.where(:table => self.table_name).all can_edit = false @@layers.each do |layer| # check if any layer with this table is editable if ability.can?(:edit, layer) can_edit = true break end end can_edit end |
.extent_field ⇒ Object
33 34 35 |
# File 'app/models/geo_model.rb', line 33 def self.extent_field "ST_Envelope(#{table_name}.#{geometry_column_name}) AS extent" end |
.forbidden(ability) ⇒ Object
151 152 153 154 155 156 157 158 |
# File 'app/models/geo_model.rb', line 151 def self.forbidden(ability) if ability.nil? logger.info "----> Edit access forbidden without login" else logger.info "----> Edit access forbidden with roles #{ability.roles.collect(&:name).join('+')}!" end where('1=0') # No access end |
.geo_factory ⇒ Object
172 173 174 175 176 177 178 179 180 |
# File 'app/models/geo_model.rb', line 172 def self.geo_factory if self.rgeo_factory_generator == RGeo::ActiveRecord::DEFAULT_FACTORY_GENERATOR self.rgeo_factory_generator = RGeo::Geos.factory_generator rgeo_factory_settings.set_column_factory(table_name, geometry_column_name, 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') ) end rgeo_factory_for_column(geometry_column_name) end |
.geojson_decode(json) ⇒ Object
90 91 92 |
# File 'app/models/geo_model.rb', line 90 def self.geojson_decode(json) RGeo::GeoJSON.decode(json, :json_parser => :json, :geo_factory => geo_factory) end |
.geometry_column ⇒ Object
27 28 29 30 31 |
# File 'app/models/geo_model.rb', line 27 def self.geometry_column col = columns_hash[geometry_column_name] col.instance_eval { @srid = srid } col end |
.geometry_column_info ⇒ Object
8 9 10 11 12 13 |
# File 'app/models/geo_model.rb', line 8 def self.geometry_column_info #spatial_column_info returns key/value list with geometry_column name as key #value example: {:srid=>21781, :type=>"MULTIPOLYGON", :dimension=>2, :has_z=>false, :has_m=>false, :name=>"the_geom"} #We take the first matching entry @geometry_column_info ||= connection.spatial_column_info(table_name).values.first end |
.geometry_column_name ⇒ Object
15 16 17 |
# File 'app/models/geo_model.rb', line 15 def self.geometry_column_name geometry_column_info[:name] end |
.geometry_type ⇒ Object
19 20 21 |
# File 'app/models/geo_model.rb', line 19 def self.geometry_type geometry_column_info[:type] end |
.identify_filter(searchgeo, radius) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'app/models/geo_model.rb', line 41 def self.identify_filter(searchgeo, radius) if searchgeo[0..3] == "POLY" logger.debug "*** POLY-query: #{searchgeo} ***" polygon = "ST_GeomFromText('#{searchgeo}', #{srid})" scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{polygon}, #{radius})") else if searchgeo.split(',').length == 3 logger.debug "*** CIRCLE-query: #{searchgeo} ***" x1, y1, r = searchgeo.split(',').collect(&:to_f) center = "ST_GeomFromText('POINT(#{x1} #{y1})', #{srid})" scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{center}, #{r})") else logger.debug "*** BBOX-query: #{searchgeo} ***" x1, y1, x2, y2 = searchgeo.split(',').collect(&:to_f) center = "ST_GeomFromText('POINT(#{x1+(x2-x1)/2} #{y1+(y2-y1)/2})', #{srid})" scoped.where("ST_DWithin(#{table_name}.#{geometry_column_name}, #{center}, #{radius})") end end end |
.srid ⇒ Object
23 24 25 |
# File 'app/models/geo_model.rb', line 23 def self.srid geometry_column_info[:srid] end |
.user_filter(ability) ⇒ Object
apply user filter for editing Override in descendant classes
141 142 143 144 145 146 147 148 149 |
# File 'app/models/geo_model.rb', line 141 def self.user_filter(ability) if ability.nil? forbidden(ability) elsif can_edit?(ability) scoped #No filter else forbidden(ability) end end |
Instance Method Details
#bbox ⇒ Object
Custom identify query def self.identify_query(bbox, radius)
scoped.select().where()....
end
66 67 68 69 |
# File 'app/models/geo_model.rb', line 66 def bbox envelope = GeoRuby::SimpleFeatures::Geometry.from_hex_ewkb(extent).envelope #TODO: replace with rgeo [envelope.lower_corner.x, envelope.lower_corner.y, envelope.upper_corner.x, envelope.upper_corner.y] end |
#csv_header ⇒ Object
header for CSV export
161 162 163 164 |
# File 'app/models/geo_model.rb', line 161 def csv_header #empty by default [] end |
#csv_row ⇒ Object
row values for CSV export
167 168 169 170 |
# File 'app/models/geo_model.rb', line 167 def csv_row #empty by default [] end |
#modified_by(user) ⇒ Object
update modification attributes (changed_by, etc.) Override in descendant classes
122 123 124 |
# File 'app/models/geo_model.rb', line 122 def modified_by(user) #none by default end |
#to_geojson(options = {}) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'app/models/geo_model.rb', line 94 def to_geojson( = {}) only = .delete(:only) geoson = { :type => 'Feature' } geoson[:properties] = attributes.delete_if do |name, value| # TODO: support for multiple geometry columns if name == self.class.geometry_column_name geoson[:geometry] = value true elsif name == self.class.primary_key then geoson[:id] = value true elsif only !only.include?(name.to_sym) end end geoson.to_json end |
#update_attributes_from_geojson_feature(feature, user) ⇒ Object
112 113 114 115 116 117 118 |
# File 'app/models/geo_model.rb', line 112 def update_attributes_from_geojson_feature(feature, user) attr = feature.properties attr[self.class.geometry_column_name] = feature.geometry ok = update_attributes(attr) modified_by(user) ok end |