spatial_features 2.7.4 → 2.7.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eca12b6b107350864c5a353d6a7fe587676c1661e1d54bd8cbccb57733e49926
4
- data.tar.gz: 7272b1807b1335b7ea22fc1cae398780f13acd095f5d5c8a0436dfa2ed6c6b17
3
+ metadata.gz: 13dafdeb45681a5a529ee77c0c54d8306d35858e7c715c8f6845bf7bac4ff51e
4
+ data.tar.gz: 9789d728e2a2fcd7cb3903637bb3fa61c01e323c99b38bf677fbfcdc06cc2bb4
5
5
  SHA512:
6
- metadata.gz: eec0cf39ea56064d74eb3b7efc90be1903377dd9035f5e0be8a8de8b4cb6088ab607087b025f7bee1178f6a974386dd74b59f1f4f5045b5af3959d25eb8669d5
7
- data.tar.gz: bce6ce396af2a8ba10f11eded504d26e00be348ca15211ba04adca5310698b11e66a177fe0d081a0511d94a14eed89b8d8f280db0de54cc0019895b6a7d67eab
6
+ metadata.gz: f0f614d22d3df5c3fbdeda0875d95b31b7a2b843ee012aafa240996a3ffe6ea00c1854b470945dcf3151ed3427daac680856c176b72419fad3f18dfa00418307
7
+ data.tar.gz: e0b1535e925c8376fcfb20a13e70d1f1ae80dcfc7b709f755140aae94b70f8118dd95c7cd040d7f8441493d79d339e106838e3f757cac7eec2249023b0f7657c
@@ -3,7 +3,7 @@ class SpatialCache < ActiveRecord::Base
3
3
 
4
4
  def self.between(spatial_model, klass)
5
5
  where(SpatialFeatures::Utils.polymorphic_condition(spatial_model, 'spatial_model'))
6
- .where(:intersection_model_type => klass.to_s)
6
+ .where(:intersection_model_type => SpatialFeatures::Utils.class_name_with_ancestors(klass))
7
7
  end
8
8
 
9
9
  def stale?
@@ -3,7 +3,7 @@ module SpatialFeatures
3
3
  self.default_cache_buffer_in_meters = 100
4
4
 
5
5
  def self.update_proximity(*klasses)
6
- klasses.permutation(2).each do |klass, clazz|
6
+ class_permutations(klasses).each do |klass, clazz|
7
7
  klass.without_spatial_cache(clazz).find_each do |record|
8
8
  cache_record_proximity(record, clazz)
9
9
  end
@@ -26,7 +26,7 @@ module SpatialFeatures
26
26
  # NOTE: Arguments are order independent, so their names do not reflect the _a _b
27
27
  # naming scheme used in other cache methods
28
28
  def self.cache_proximity(*klasses)
29
- klasses.combination(2).each do |klass, clazz|
29
+ class_combinations(klasses).each do |klass, clazz|
30
30
  clear_cache(klass, clazz)
31
31
 
32
32
  klass.find_each do |record|
@@ -40,6 +40,16 @@ module SpatialFeatures
40
40
  end
41
41
  end
42
42
 
43
+ # Returns a list of class pairs with each combination e.g. [a,b], [a,c] [b,c] and also [a,a], [b,b], [c,c]
44
+ def self.class_combinations(klasses)
45
+ klasses.zip(klasses) + klasses.combination(2).to_a
46
+ end
47
+
48
+ # Returns a list of class pairs with each permutation e.g. [a,b], [b,a] and also [a,a], [b,b]
49
+ def self.class_permutations(klasses)
50
+ klasses.zip(klasses) + klasses.permutation(2).to_a
51
+ end
52
+
43
53
  # Create or update the spatial cache of a single record in relation to another spatial class
44
54
  def self.cache_record_proximity(record, klass)
45
55
  clear_record_cache(record, klass)
@@ -59,14 +69,14 @@ module SpatialFeatures
59
69
  end
60
70
 
61
71
  def self.clear_record_cache(record, klass)
62
- record.spatial_caches.where(:intersection_model_type => klass.to_s).delete_all
72
+ record.spatial_caches.where(:intersection_model_type => SpatialFeatures::Utils.class_name_with_ancestors(klass)).delete_all
63
73
  SpatialProximity.between(record, klass).delete_all
64
74
  end
65
75
 
66
76
  def self.create_spatial_proximities(record, klass)
67
77
  klass = klass.to_s.constantize
68
78
  klass_record = klass.new
69
- model_a, model_b = record.class.to_s < klass.to_s ? [record, klass_record] : [klass_record, record]
79
+ model_a, model_b = Utils.base_class(record).to_s < Utils.base_class(klass).to_s ? [record, klass_record] : [klass_record, record]
70
80
 
71
81
  scope = klass.within_buffer(record, default_cache_buffer_in_meters, :columns => :id, :intersection_area => true, :distance => true, :cache => false)
72
82
  results = klass.connection.select_rows(scope.to_sql)
@@ -76,9 +86,9 @@ module SpatialFeatures
76
86
  SpatialProximity.create! do |proximity|
77
87
  # Set id and type instead of model to avoid autosaving the klass_record
78
88
  proximity.model_a_id = model_a.id
79
- proximity.model_a_type = model_a.class
89
+ proximity.model_a_type = Utils.base_class(model_a)
80
90
  proximity.model_b_id = model_b.id
81
- proximity.model_b_type = model_b.class
91
+ proximity.model_b_type = Utils.base_class(model_b)
82
92
  proximity.distance_in_meters = distance
83
93
  proximity.intersection_area_in_square_meters = area
84
94
  end
@@ -13,10 +13,10 @@ module SpatialFeatures
13
13
  has_many :features, lambda { extending FeaturesAssociationExtensions }, :as => :spatial_model, :dependent => :delete_all
14
14
 
15
15
  scope :with_features, lambda { joins(:features).uniq }
16
- scope :without_features, lambda { joins("LEFT OUTER JOIN features ON features.spatial_model_type = '#{name}' AND features.spatial_model_id = #{table_name}.id").where("features.id IS NULL") }
16
+ scope :without_features, lambda { joins("LEFT OUTER JOIN features ON features.spatial_model_type = '#{Utils.base_class(name)}' AND features.spatial_model_id = #{table_name}.id").where("features.id IS NULL") }
17
17
 
18
- scope :with_spatial_cache, lambda {|klass| joins(:spatial_caches).where(:spatial_caches => { :intersection_model_type => klass }).uniq }
19
- scope :without_spatial_cache, lambda {|klass| joins("LEFT OUTER JOIN #{SpatialCache.table_name} ON #{SpatialCache.table_name}.spatial_model_id = #{table_name}.id AND #{SpatialCache.table_name}.spatial_model_type = '#{name}' and intersection_model_type = '#{klass}'").where("#{SpatialCache.table_name}.spatial_model_id IS NULL") }
18
+ scope :with_spatial_cache, lambda {|klass| joins(:spatial_caches).where(:spatial_caches => { :intersection_model_type => Utils.class_name_with_ancestors(klass) }).uniq }
19
+ scope :without_spatial_cache, lambda {|klass| joins("LEFT OUTER JOIN #{SpatialCache.table_name} ON #{SpatialCache.table_name}.spatial_model_id = #{table_name}.id AND #{SpatialCache.table_name}.spatial_model_type = '#{Utils.base_class(name)}' and intersection_model_type IN ('#{Utils.class_name_with_ancestors(klass).join("','") }')").where("#{SpatialCache.table_name}.spatial_model_id IS NULL") }
20
20
  scope :with_stale_spatial_cache, lambda { joins(:spatial_caches).where("#{table_name}.features_hash != spatial_caches.features_hash").uniq } if has_spatial_features_hash?
21
21
 
22
22
  has_many :spatial_caches, :as => :spatial_model, :dependent => :delete_all, :class_name => 'SpatialCache'
@@ -113,12 +113,13 @@ module SpatialFeatures
113
113
  end
114
114
 
115
115
  def cached_spatial_join(other)
116
- other_class = Utils.class_of(other)
116
+ other_class = Utils.base_class_of(other)
117
+ self_class = Utils.base_class_of(self)
117
118
 
118
- other_column = other_class.name < self.name ? :model_a : :model_b
119
+ other_column = other_class.name < self_class.name ? :model_a : :model_b
119
120
  self_column = other_column == :model_a ? :model_b : :model_a
120
121
 
121
- joins("INNER JOIN spatial_proximities ON spatial_proximities.#{self_column}_type = '#{self}' AND spatial_proximities.#{self_column}_id = #{table_name}.id AND spatial_proximities.#{other_column}_type = '#{other_class}' AND spatial_proximities.#{other_column}_id IN (#{Utils.id_sql(other)})")
122
+ joins("INNER JOIN spatial_proximities ON spatial_proximities.#{self_column}_type = '#{self_class}' AND spatial_proximities.#{self_column}_id = #{table_name}.id AND spatial_proximities.#{other_column}_type = '#{other_class}' AND spatial_proximities.#{other_column}_id IN (#{Utils.id_sql(other)})")
122
123
  end
123
124
 
124
125
  def uncached_within_buffer_scope(other, buffer_in_meters, options)
@@ -153,7 +154,7 @@ module SpatialFeatures
153
154
 
154
155
  def features_scope(other)
155
156
  scope = Feature
156
- scope = scope.where(:spatial_model_type => Utils.class_of(other))
157
+ scope = scope.where(:spatial_model_type => Utils.base_class_of(other))
157
158
  scope = scope.where(:spatial_model_id => other) unless Utils.class_of(other) == other
158
159
  return scope
159
160
  end
@@ -205,7 +206,7 @@ module SpatialFeatures
205
206
  end
206
207
 
207
208
  def spatial_cache_for?(other, buffer_in_meters)
208
- if cache = spatial_caches.between(self, SpatialFeatures::Utils.class_of(other)).first
209
+ if cache = spatial_caches.between(self, Utils.class_of(other)).first
209
210
  return cache.intersection_cache_distance.nil? if buffer_in_meters.nil? # cache must be total if no buffer_in_meters
210
211
  return false if cache.stale? # cache must be for current features
211
212
  return true if cache.intersection_cache_distance.nil? # always good if cache is total
@@ -6,7 +6,26 @@ module SpatialFeatures
6
6
  sql = "#{column_name}_type = ?"
7
7
  sql << " AND #{column_name}_id IN (#{id_sql(scope)})" unless scope.is_a?(Class)
8
8
 
9
- return class_of(scope).send :sanitize_sql, [sql, class_of(scope)]
9
+ return class_of(scope).send :sanitize_sql, [sql, base_class_of(scope)]
10
+ end
11
+
12
+ def class_name_with_ancestors(object)
13
+ class_of(object).ancestors.select {|k| k < ActiveRecord::Base }.map(&:to_s)
14
+ end
15
+
16
+ def base_class_of(object)
17
+ base_class(class_of(object))
18
+ end
19
+
20
+ def base_class(klass)
21
+ case klass
22
+ when String
23
+ klass.constantize.base_class.to_s
24
+ when ActiveRecord::Base
25
+ klass.class.base_class
26
+ when Class
27
+ klass.base_class
28
+ end
10
29
  end
11
30
 
12
31
  # Returns the class for the given, class, scope, or record
@@ -29,7 +29,7 @@ module SpatialFeatures
29
29
  if options[:target]
30
30
  sql <<
31
31
  "INNER JOIN features
32
- ON features.spatial_model_type = '#{options[:target].class}' AND features.spatial_model_id = #{options[:target].id} AND ST_Intersects(features.geom, venn_polygons.geom) "
32
+ ON features.spatial_model_type = '#{Utils.base_class(options[:target].class)}' AND features.spatial_model_id = #{options[:target].id} AND ST_Intersects(features.geom, venn_polygons.geom) "
33
33
  end
34
34
 
35
35
  # Join with the original polygons so we can determine which original polygons each venn polygon came from
@@ -1,3 +1,3 @@
1
1
  module SpatialFeatures
2
- VERSION = "2.7.4"
2
+ VERSION = "2.7.5"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spatial_features
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.4
4
+ version: 2.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Wallace
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-06-24 00:00:00.000000000 Z
12
+ date: 2019-07-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails