spatial_features 2.7.4 → 2.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/models/spatial_cache.rb +1 -1
- data/lib/spatial_features/caching.rb +16 -6
- data/lib/spatial_features/has_spatial_features.rb +9 -8
- data/lib/spatial_features/utils.rb +20 -1
- data/lib/spatial_features/venn_polygons.rb +1 -1
- data/lib/spatial_features/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13dafdeb45681a5a529ee77c0c54d8306d35858e7c715c8f6845bf7bac4ff51e
|
4
|
+
data.tar.gz: 9789d728e2a2fcd7cb3903637bb3fa61c01e323c99b38bf677fbfcdc06cc2bb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0f614d22d3df5c3fbdeda0875d95b31b7a2b843ee012aafa240996a3ffe6ea00c1854b470945dcf3151ed3427daac680856c176b72419fad3f18dfa00418307
|
7
|
+
data.tar.gz: e0b1535e925c8376fcfb20a13e70d1f1ae80dcfc7b709f755140aae94b70f8118dd95c7cd040d7f8441493d79d339e106838e3f757cac7eec2249023b0f7657c
|
data/app/models/spatial_cache.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
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.
|
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
|
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
|
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
|
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.
|
116
|
+
other_class = Utils.base_class_of(other)
|
117
|
+
self_class = Utils.base_class_of(self)
|
117
118
|
|
118
|
-
other_column = other_class.name <
|
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 = '#{
|
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.
|
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,
|
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,
|
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
|
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
|
+
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-
|
12
|
+
date: 2019-07-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|