module SpatialFeatures::InstanceMethods

Public Instance Methods

acts_like_spatial_features?() click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 172
def acts_like_spatial_features?
  true
end
aggregate_features() click to toggle source

Scope to perform SQL-only calculations on a record's aggregate feature. This avoids loading the large data payload if all that is needed is metadata

# File lib/spatial_features/has_spatial_features.rb, line 246
def aggregate_features
  self.class.where(id: id).aggregate_features
end
bounds() click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 204
def bounds
  if association(:aggregate_feature).loaded?
    aggregate_feature&.feature_bounds
  else
    result = aggregate_features.pluck(:north, :east, :south, :west).first
    [:north, :east, :south, :west].zip(result.map {|bound| BigDecimal(bound) }).to_h.with_indifferent_access if result
  end
end
features?() click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 192
def features?
  if features.loaded?
    features.present?
  else
    features.exists?
  end
end
features_area_in_square_meters() click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 219
def features_area_in_square_meters
  if association(:aggregate_feature).loaded?
    aggregate_feature&.area
  else
    aggregate_features.pluck(:area).first
  end
end
features_cache_key() click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 176
def features_cache_key
  "#{self.class.name}/#{id}-#{has_spatial_features_hash? ? features_hash : aggregate_feature.cache_key}"
end
intersects?(other) click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 200
def intersects?(other)
  self.class.unscoped { self.class.intersecting(other).exists?(id) }
end
lines?() click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 184
def lines?
  !features.lines.empty?
end
points?() click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 188
def points?
  !features.points.empty?
end
polygons?() click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 180
def polygons?
  !features.polygons.empty?
end
spatial_cache_for?(other, buffer_in_meters) click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 233
def spatial_cache_for?(other, buffer_in_meters)
  if cache = spatial_caches.between(self, Utils.class_of(other)).first
    return cache.intersection_cache_distance.nil? if buffer_in_meters.nil? # cache must be total if no buffer_in_meters
    return false if cache.stale? # cache must be for current features
    return true if cache.intersection_cache_distance.nil? # always good if cache is total

    return buffer_in_meters <= cache.intersection_cache_distance
  else
    return false
  end
end
total_intersection_area_in_square_meters(other) click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 227
def total_intersection_area_in_square_meters(other)
  other = other.intersecting(self) unless other.is_a?(ActiveRecord::Base)
  return features.area if spatial_cache_for?(other, 0) && SpatialProximity.between(self, other).where('intersection_area_in_square_meters >= ?', features.area).exists?
  return features.total_intersection_area_in_square_meters(other.features)
end
total_intersection_area_percentage(klass) click to toggle source
# File lib/spatial_features/has_spatial_features.rb, line 213
def total_intersection_area_percentage(klass)
  return 0.0 unless features_area_in_square_meters > 0

  ((total_intersection_area_in_square_meters(klass) / features_area_in_square_meters) * 100).round(1)
end