Class: GeoModel

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/geo_model.rb

Direct Known Subclasses

SearchModel

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.bbox_filter(params) ⇒ Object

based on mapfish_filter



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'app/models/geo_model.rb', line 49

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

Returns:

  • (Boolean)


103
104
105
106
107
108
109
110
111
112
113
114
# File 'app/models/geo_model.rb', line 103

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



128
129
130
131
132
133
134
135
# File 'app/models/geo_model.rb', line 128

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



149
150
151
152
153
154
155
156
157
# File 'app/models/geo_model.rb', line 149

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



67
68
69
# File 'app/models/geo_model.rb', line 67

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(bbox, radius) ⇒ Object



37
38
39
40
41
# File 'app/models/geo_model.rb', line 37

def self.identify_filter(bbox, radius)
  x1, y1, x2, y2 = bbox.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

.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



118
119
120
121
122
123
124
125
126
# File 'app/models/geo_model.rb', line 118

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



43
44
45
46
# File 'app/models/geo_model.rb', line 43

def bbox
  envelope = GeoRuby::SimpleFeatures::Geometry.from_hex_ewkb(extent).envelope
  [envelope.lower_corner.x, envelope.lower_corner.y, envelope.upper_corner.x, envelope.upper_corner.y]
end

#csv_header ⇒ Object

header for CSV export



138
139
140
141
# File 'app/models/geo_model.rb', line 138

def csv_header
  #empty by default
  []
end

#csv_row ⇒ Object

row values for CSV export



144
145
146
147
# File 'app/models/geo_model.rb', line 144

def csv_row
  #empty by default
  []
end

#modified_by(user) ⇒ Object

update modification attributes (changed_by, etc.) Override in descendant classes



99
100
101
# File 'app/models/geo_model.rb', line 99

def modified_by(user)
  #none by default
end

#to_geojson(options = {}) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/models/geo_model.rb', line 71

def to_geojson(options = {})
  only = options.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



89
90
91
92
93
94
95
# File 'app/models/geo_model.rb', line 89

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