spatial_features 2.1.6 → 2.1.7

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
  SHA1:
3
- metadata.gz: ca9589fa4acf1bb8c8d5c4a915891628c298b80c
4
- data.tar.gz: b450b7c37ffa34bfd87731493916f3a20210b414
3
+ metadata.gz: 86ef03aa25c8f1b883c2dfc313ca200eb26f22b0
4
+ data.tar.gz: 25b5c3887d7b9cf1cb560d7b0baf38cc4fdd6f73
5
5
  SHA512:
6
- metadata.gz: cbdd1f67b29366a08858491b4d8c3c0deaeab2e8feebfd335b07c7d90ca38908b5d750834c9dc46336c038bb77cb2ef60a47405029ad412ddf4c7b87387c583e
7
- data.tar.gz: 7c03e44c03b576eec2bd88c5524f3925b7e78579b9d927fa6aa79ead01c7e92425c012a8c63e3f3bd8cacfc1727b69bf9c66908ac3f3c0b9cdb219a5aa6bccbf
6
+ metadata.gz: c437c6f85a9bf15ecd88637d09a348a92498a9e450a4885731e4daedff1c04fbcd626a9ffd4e6ac1430da612b794fc4b8f5ecff62a7c1039c295bab8f39ddbf7
7
+ data.tar.gz: 503b88e79c31b67c0069b5cb1346b26879f782227234e82e4bdcfc0b080ea920418767a333b6a1f5b9d30f43375bf3e5a666e0c2915505d8fbf38097e486839e
@@ -7,10 +7,9 @@ class Feature < ActiveRecord::Base
7
7
 
8
8
  before_validation :sanitize_feature_type
9
9
  validates_presence_of :geog
10
- validate :geometry_is_valid
10
+ validate :validate_geometry
11
11
  validates_inclusion_of :feature_type, :in => FEATURE_TYPES
12
12
  before_save :sanitize
13
- before_save :make_valid, if: :make_valid?
14
13
  after_save :cache_derivatives
15
14
 
16
15
  def self.with_metadata(k, v)
@@ -111,7 +110,7 @@ class Feature < ActiveRecord::Base
111
110
  private
112
111
 
113
112
  def make_valid
114
- self.geog = ActiveRecord::Base.connection.select_value("SELECT ST_CollectionExtract(ST_MakeValid('#{sanitize}'),3)")
113
+ self.geog = ActiveRecord::Base.connection.select_value("SELECT ST_Buffer('#{sanitize}', 0)")
115
114
  end
116
115
 
117
116
  # Use ST_Force2D to discard z-coordinates that cause failures later in the process
@@ -127,13 +126,24 @@ class Feature < ActiveRecord::Base
127
126
  joins('INNER JOIN features AS other_features ON true').where(:other_features => {:id => other})
128
127
  end
129
128
 
130
- def geometry_is_valid
131
- if geog?
132
- instance = self.class.unscoped.invalid.from("(SELECT '#{sanitize_input_for_sql(self.geog)}'::geometry AS geog) #{self.class.table_name}").to_a.first
133
- errors.add :geog, instance.invalid_geometry_message if instance
129
+ def validate_geometry
130
+ return unless geog?
131
+
132
+ error = geometry_validation_message
133
+ if error && make_valid?
134
+ make_valid
135
+ self.make_valid = false
136
+ validate_geometry
137
+ elsif error
138
+ errors.add :geog, error
134
139
  end
135
140
  end
136
141
 
142
+ def geometry_validation_message
143
+ error = self.class.connection.select_one(self.class.unscoped.invalid.from("(SELECT '#{sanitize_input_for_sql(self.geog)}'::geometry AS geog) #{self.class.table_name}"))
144
+ return error.fetch('invalid_geometry_message') if error
145
+ end
146
+
137
147
  def sanitize_feature_type
138
148
  self.feature_type = FEATURE_TYPES.find {|type| self.feature_type.to_s.strip.downcase.include?(type) }
139
149
  end
@@ -7,7 +7,7 @@ module SpatialFeatures
7
7
  include DelayedFeatureImport
8
8
 
9
9
  class_attribute :spatial_features_options
10
- self.spatial_features_options = {}
10
+ self.spatial_features_options = {:make_valid => true}
11
11
 
12
12
  has_many :features, lambda { extending FeaturesAssociationExtensions }, :as => :spatial_model, :dependent => :delete_all
13
13
 
@@ -19,8 +19,7 @@ module SpatialFeatures
19
19
  return if features_cache_key_matches?(cache_key)
20
20
 
21
21
  run_callbacks :update_features do
22
- import_features(imports)
23
- validate_features!(imports, skip_invalid)
22
+ import_features(imports, skip_invalid)
24
23
  set_features_cache_key(cache_key)
25
24
  end
26
25
 
@@ -37,25 +36,23 @@ module SpatialFeatures
37
36
  end.compact
38
37
  end
39
38
 
40
- def import_features(imports)
41
- self.features.destroy_all
42
- self.features = imports.flat_map(&:features)
43
- end
44
-
45
- def validate_features!(imports, skip_invalid = false)
46
- invalid = features.select {|feature| feature.errors.present? }
47
- features.destroy(invalid)
48
-
49
- return if skip_invalid
50
-
51
- errors = imports.flat_map(&:errors)
52
- invalid.each do |feature|
53
- errors << "Feature #{feature.name}: #{feature.errors.full_messages.to_sentence}"
39
+ def import_features(imports, skip_invalid)
40
+ self.features.delete_all
41
+ valid, invalid = imports.flat_map(&:features).partition do |feature|
42
+ feature.spatial_model = self
43
+ feature.save
54
44
  end
55
45
 
56
- if errors.present?
46
+ if !skip_invalid && invalid.present?
47
+ errors = imports.flat_map(&:errors)
48
+ invalid.each do |feature|
49
+ errors << "Feature #{feature.name}: #{feature.errors.full_messages.to_sentence}"
50
+ end
51
+
57
52
  raise ImportError, "Error updating #{self.class} #{self.id}. #{errors.to_sentence}"
58
53
  end
54
+
55
+ self.features = valid
59
56
  end
60
57
 
61
58
  def features_cache_key_matches?(cache_key)
@@ -1,3 +1,3 @@
1
1
  module SpatialFeatures
2
- VERSION = "2.1.6"
2
+ VERSION = "2.1.7"
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.1.6
4
+ version: 2.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Wallace