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_meters(geom = 'geom_lowres') ⇒ Object



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

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

.cache_derivatives(options = {}) ⇒ Object



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
99
100
101
# File 'app/models/feature.rb', line 71

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



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

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



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

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, geom = 'geom_lowres') ⇒ Object



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

def self.total_intersection_area_in_square_meters(other_features, geom = 'geom_lowres')
  scope = unscope(:select).select("ST_Union(#{geom}) AS geom").polygons
  other_scope = other_features.polygons

  query = unscoped.select('ST_Area(ST_Intersection(ST_Union(features.geom), ST_Union(other_features.geom)))')
                  .from(scope, "features")
                  .joins("INNER JOIN (#{other_scope.to_sql}) AS other_features ON ST_Intersects(features.geom, other_features.geom)")
  return connection.select_value(query).to_f
end

.validObject



58
59
60
# File 'app/models/feature.rb', line 58

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



107
108
109
# File 'app/models/feature.rb', line 107

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

#envelope(buffer_in_meters = 0) ⇒ Object



62
63
64
65
66
67
68
69
# File 'app/models/feature.rb', line 62

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



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

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

#kml(options = {}) ⇒ Object



111
112
113
114
115
# File 'app/models/feature.rb', line 111

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)


117
118
119
# File 'app/models/feature.rb', line 117

def make_valid?
  @make_valid
end