Class: Feature

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

Constant Summary collapse

FEATURE_TYPES =
%w(polygon point line)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#make_valid=(value) ⇒ Object

Sets the attribute make_valid

Parameters:

  • value

    the value to set the attribute make_valid to.



4
5
6
# File 'app/models/feature.rb', line 4

def make_valid=(value)
  @make_valid = value
end

Class Method Details

.area_in_square_metersObject



35
36
37
38
# File 'app/models/feature.rb', line 35

def self.area_in_square_meters
  current_scope = all
  unscoped { connection.select_value(select('ST_Area(ST_Union(geom))').from(current_scope, :features)).to_f }
end

.cache_derivatives(options = {}) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/models/feature.rb', line 68

def self.cache_derivatives(options = {})
  options.reverse_merge! :lowres_simplification => 2, :lowres_precision => 5

  update_all <<-SQL.squish
    geom         = ST_Transform(geog::geometry, #{detect_srid('geom')}),
    north        = ST_YMax(geog::geometry),
    east         = ST_XMax(geog::geometry),
    south        = ST_YMin(geog::geometry),
    west         = ST_XMin(geog::geometry),
    area         = ST_Area(geog),
    centroid     = ST_PointOnSurface(geog::geometry)
  SQL

  invalid('geom').update_all <<-SQL.squish
    geom         = ST_Buffer(geom, 0)
  SQL

  update_all <<-SQL.squish
    geom_lowres  = ST_SimplifyPreserveTopology(geom, #{options[:lowres_simplification]})
  SQL

  invalid('geom_lowres').update_all <<-SQL.squish
    geom_lowres  = ST_Buffer(geom_lowres, 0)
  SQL

  update_all <<-SQL.squish
    kml          = ST_AsKML(geog, 6),
    kml_lowres   = ST_AsKML(geom_lowres, #{options[:lowres_precision]}),
    kml_centroid = ST_AsKML(centroid)
  SQL
end

.intersecting(other) ⇒ Object



47
48
49
# File 'app/models/feature.rb', line 47

def self.intersecting(other)
  join_other_features(other).where('ST_Intersects(features.geom_lowres, other_features.geom_lowres)').uniq
end

.invalid(column = 'geog::geometry') ⇒ Object



51
52
53
# File 'app/models/feature.rb', line 51

def self.invalid(column = 'geog::geometry')
  select("features.*, ST_IsValidReason(#{column}) AS invalid_geometry_message").where.not("ST_IsValid(#{column})")
end

.linesObject



27
28
29
# File 'app/models/feature.rb', line 27

def self.lines
  where(:feature_type => 'line')
end

.pointsObject



31
32
33
# File 'app/models/feature.rb', line 31

def self.points
  where(:feature_type => 'point')
end

.polygonsObject



23
24
25
# File 'app/models/feature.rb', line 23

def self.polygons
  where(:feature_type => 'polygon')
end

.total_intersection_area_in_square_meters(other_features) ⇒ Object



40
41
42
43
44
45
# File 'app/models/feature.rb', line 40

def self.total_intersection_area_in_square_meters(other_features)
  unscoped
    .from("(#{select("ST_Union(geom) AS geom").to_sql}) features, (#{other_features.to_sql}) other_features")
    .pluck('ST_Area(ST_UNION(ST_Intersection(features.geom, other_features.geom)))')
    .first.to_f
end

.validObject



55
56
57
# File 'app/models/feature.rb', line 55

def self.valid
  where('ST_IsValid(geog::geometry)')
end

.with_metadata(k, v) ⇒ Object



15
16
17
18
19
20
21
# File 'app/models/feature.rb', line 15

def self.(k, v)
  if k.present? && v.present?
    where('metadata->? = ?', k, v)
  else
    all
  end
end

Instance Method Details

#cache_derivatives(*args) ⇒ Object



104
105
106
# File 'app/models/feature.rb', line 104

def cache_derivatives(*args)
  self.class.where(:id => self.id).cache_derivatives(*args)
end

#envelope(buffer_in_meters = 0) ⇒ Object



59
60
61
62
63
64
65
66
# File 'app/models/feature.rb', line 59

def envelope(buffer_in_meters = 0)
  envelope_json = JSON.parse(self.class.select("ST_AsGeoJSON(ST_Envelope(ST_Buffer(features.geog, #{buffer_in_meters})::geometry)) AS result").where(:id => id).first.result)
  envelope_json = envelope_json["coordinates"].first

  raise "Can't calculate envelope for Feature #{self.id}" if envelope_json.blank?

  return envelope_json.values_at(0,2)
end

#feature_boundsObject



100
101
102
# File 'app/models/feature.rb', line 100

def feature_bounds
  {n: north, e: east, s: south, w: west}
end

#kml(options = {}) ⇒ Object



108
109
110
111
112
# File 'app/models/feature.rb', line 108

def kml(options = {})
  geometry = options[:lowres] ? kml_lowres : super()
  geometry = "<MultiGeometry>#{geometry}#{kml_centroid}</MultiGeometry>" if options[:centroid]
  return geometry
end

#make_valid?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'app/models/feature.rb', line 114

def make_valid?
  @make_valid
end