Class: AbstractFeature

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

Direct Known Subclasses

AggregateFeature, Feature

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.



9
10
11
# File 'app/models/abstract_feature.rb', line 9

def make_valid=(value)
  @make_valid = value
end

Class Method Details

.area_in_square_meters(geom = 'geom_lowres') ⇒ Object



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

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



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/abstract_feature.rb', line 79

def self.cache_derivatives(options = {})
  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.fetch(:lowres_simplification, lowres_simplification)})
  SQL

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

.cache_keyObject



19
20
21
# File 'app/models/abstract_feature.rb', line 19

def self.cache_key
  "#{maximum(:id)}-#{count}"
end

.intersecting(other) ⇒ Object



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

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



62
63
64
# File 'app/models/abstract_feature.rb', line 62

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

.linesObject



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

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

.pointsObject



39
40
41
# File 'app/models/abstract_feature.rb', line 39

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

.polygonsObject



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

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

.total_intersection_area_in_square_meters(other_features, geom = 'geom_lowres') ⇒ Object



48
49
50
51
52
53
54
55
56
# File 'app/models/abstract_feature.rb', line 48

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 = base_class.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



66
67
68
# File 'app/models/abstract_feature.rb', line 66

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

.with_metadata(k, v) ⇒ Object



23
24
25
26
27
28
29
# File 'app/models/abstract_feature.rb', line 23

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/abstract_feature.rb', line 107

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

#envelope(buffer_in_meters = 0) ⇒ Object



70
71
72
73
74
75
76
77
# File 'app/models/abstract_feature.rb', line 70

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/abstract_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/abstract_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/abstract_feature.rb', line 117

def make_valid?
  @make_valid
end