Module: SpatialFeatures::InstanceMethods
- Defined in:
- lib/spatial_features/has_spatial_features.rb
Instance Method Summary collapse
- #acts_like_spatial_features? ⇒ Boolean
-
#aggregate_features ⇒ Object
Scope to perform SQL-only calculations on a record’s aggregate feature.
- #bounds ⇒ Object
- #features? ⇒ Boolean
- #features_area_in_square_meters ⇒ Object
- #features_cache_key ⇒ Object
- #intersects?(other) ⇒ Boolean
- #lines? ⇒ Boolean
- #points? ⇒ Boolean
- #polygons? ⇒ Boolean
- #spatial_cache_for?(other, buffer_in_meters) ⇒ Boolean
- #total_intersection_area_in_square_meters(other) ⇒ Object
- #total_intersection_area_percentage(klass) ⇒ Object
Instance Method Details
#acts_like_spatial_features? ⇒ Boolean
184 185 186 |
# File 'lib/spatial_features/has_spatial_features.rb', line 184 def acts_like_spatial_features? true end |
#aggregate_features ⇒ Object
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
272 273 274 |
# File 'lib/spatial_features/has_spatial_features.rb', line 272 def aggregate_features self.class.where(id: id).aggregate_features end |
#bounds ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/spatial_features/has_spatial_features.rb', line 225 def bounds @bounds ||= if has_attribute?(:north) && has_attribute?(:east) && has_attribute?(:south) && has_attribute?(:west) slice(:north, :east, :south, :west).with_indifferent_access.transform_values!(&:to_f) elsif association(:aggregate_feature).loaded? # Aggregate features can be very large and take a while to load. Avoid loading one just to load the bounds. aggregate_feature&.bounds else aggregate_features.bounds end end |
#features? ⇒ Boolean
213 214 215 216 217 218 219 |
# File 'lib/spatial_features/has_spatial_features.rb', line 213 def features? if features.loaded? features.present? else features.exists? end end |
#features_area_in_square_meters ⇒ Object
246 247 248 249 250 251 |
# File 'lib/spatial_features/has_spatial_features.rb', line 246 def features_area_in_square_meters @features_area_in_square_meters ||= area if has_attribute?(:area) # Calculated area column @features_area_in_square_meters ||= features_area if has_attribute?(:features_area) # Cached area column @features_area_in_square_meters ||= aggregate_feature&.area if association(:aggregate_feature).loaded? @features_area_in_square_meters ||= aggregate_features.pluck(:area).first end |
#features_cache_key ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/spatial_features/has_spatial_features.rb', line 188 def features_cache_key fck = if has_spatial_features_hash? features_hash elsif association(:aggregate_feature).loaded? aggregate_feature.cache_key else aggregate_features.cache_key end "#{self.class.name}/#{id}-#{fck}" end |
#intersects?(other) ⇒ Boolean
221 222 223 |
# File 'lib/spatial_features/has_spatial_features.rb', line 221 def intersects?(other) self.class.unscoped { self.class.intersecting(other).exists?(id) } end |
#lines? ⇒ Boolean
205 206 207 |
# File 'lib/spatial_features/has_spatial_features.rb', line 205 def lines? !features.lines.empty? end |
#points? ⇒ Boolean
209 210 211 |
# File 'lib/spatial_features/has_spatial_features.rb', line 209 def points? !features.points.empty? end |
#polygons? ⇒ Boolean
201 202 203 |
# File 'lib/spatial_features/has_spatial_features.rb', line 201 def polygons? !features.polygons.empty? end |
#spatial_cache_for?(other, buffer_in_meters) ⇒ Boolean
259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/spatial_features/has_spatial_features.rb', line 259 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) ⇒ Object
253 254 255 256 257 |
# File 'lib/spatial_features/has_spatial_features.rb', line 253 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) ⇒ Object
237 238 239 240 241 242 243 244 |
# File 'lib/spatial_features/has_spatial_features.rb', line 237 def total_intersection_area_percentage(klass) total_area = features_area_in_square_meters return if total_area.nil? return 0.0 if total_area.zero? ((total_intersection_area_in_square_meters(klass) / total_area) * 100).round(1) end |