Module: SpatialFeatures::ClassMethods

Defined in:
lib/spatial_features/has_spatial_features.rb

Instance Method Summary collapse

Instance Method Details

#area_in_square_metersObject



100
101
102
# File 'lib/spatial_features/has_spatial_features.rb', line 100

def area_in_square_meters
  features.area_in_square_meters
end

#covering(other) ⇒ Object



51
52
53
54
55
56
# File 'lib/spatial_features/has_spatial_features.rb', line 51

def covering(other)
  scope = joins_features_for(other).select("#{table_name}.*").group("#{table_name}.#{primary_key}")
  scope = scope.where('ST_Covers(features.geom, features_for_other.geom)')

  return scope
end

#featuresObject



70
71
72
73
74
75
76
# File 'lib/spatial_features/has_spatial_features.rb', line 70

def features
  if all == unscoped
    Feature.where(:spatial_model_type => self)
  else
    Feature.where(:spatial_model_type => self, :spatial_model_id => all.unscope(:select))
  end
end

#features_cache_keyObject

Add methods to generate cache keys for a record or all records of this class NOTE: features are never updated, only deleted and created, therefore we can tell if they have changed by finding the maximum id and count instead of needing timestamps



30
31
32
33
# File 'lib/spatial_features/has_spatial_features.rb', line 30

def features_cache_key
  # Do two separate queries because it is much faster for some reason
  "#{name}/#{features.maximum(:id)}-#{features.count}"
end

#has_features_area?Boolean

Returns true if the model stores a cache of the features area

Returns:

  • (Boolean)


96
97
98
# File 'lib/spatial_features/has_spatial_features.rb', line 96

def has_features_area?
  column_names.include? 'features_area'
end

#has_spatial_features_hash?Boolean

Returns true if the model stores a hash of the features so we don’t need to process the features if they haven’t changed

Returns:

  • (Boolean)


91
92
93
# File 'lib/spatial_features/has_spatial_features.rb', line 91

def has_spatial_features_hash?
  column_names.include? 'features_hash'
end

#intersecting(other, options = {}) ⇒ Object



35
36
37
# File 'lib/spatial_features/has_spatial_features.rb', line 35

def intersecting(other, options = {})
  within_buffer(other, 0, options)
end

#joins_features_for(other, table_alias = 'features_for') ⇒ Object

Returns a scope that includes the features for this record as the table_alias and the features for other as #table_alias_other Can be used to perform spatial calculations on the relationship between the two sets of features



80
81
82
# File 'lib/spatial_features/has_spatial_features.rb', line 80

def joins_features_for(other, table_alias = 'features_for')
  joins(:features).joins(%Q(INNER JOIN (#{other_features_union(other).to_sql}) AS "#{table_alias}_other" ON true))
end

#linesObject



62
63
64
# File 'lib/spatial_features/has_spatial_features.rb', line 62

def lines
  features.lines
end

#other_features_union(other) ⇒ Object



84
85
86
87
88
# File 'lib/spatial_features/has_spatial_features.rb', line 84

def other_features_union(other)
  scope = Feature.select('ST_Union(geom) AS geom').where(:spatial_model_type => class_for(other))
  scope = scope.where(:spatial_model_id => other) unless class_for(other) == other
  return scope
end

#pointsObject



66
67
68
# File 'lib/spatial_features/has_spatial_features.rb', line 66

def points
  features.points
end

#polygonsObject



58
59
60
# File 'lib/spatial_features/has_spatial_features.rb', line 58

def polygons
  features.polygons
end

#within_buffer(other, buffer_in_meters = 0, options = {}) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/spatial_features/has_spatial_features.rb', line 39

def within_buffer(other, buffer_in_meters = 0, options = {})
  return none if other.is_a?(ActiveRecord::Base) && other.new_record?

  # Cache only works on single records, not scopes.
  # This is because the cached intersection_area doesn't account for overlaps between the features in the scope.
  if options[:cache] != false && other.is_a?(ActiveRecord::Base)
    cached_within_buffer_scope(other, buffer_in_meters, options)
  else
    uncached_within_buffer_scope(other, buffer_in_meters, options)
  end
end