spatial_features 3.10.1 → 3.10.2
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/lib/spatial_features/has_spatial_features/feature_import.rb +8 -1
- data/lib/spatial_features/has_spatial_features/queued_spatial_processing.rb +24 -0
- data/lib/spatial_features/importers/base.rb +7 -0
- data/lib/spatial_features/importers/kml.rb +18 -1
- data/lib/spatial_features/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fdeeed7e535906a617d6fcfdf50ddf8b05acc0a588e14cade7f9ca62700b593c
|
|
4
|
+
data.tar.gz: 20886debc5f838c5cc9cc1d096867d10b1c32ad8884a836021d53ee5bc161c64
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 447c879b49a4e46931f2c2ce64f3acb3c1642f35909bf95e2c6d683eadd6205b0e393acd90cb77b90fd602b5b56e02cf2a87f511f5f8026c7cb46367a0dcfe7d
|
|
7
|
+
data.tar.gz: d5dd31db08df30837aaf1edea842e309e8d1008067cfb255c3134fdc5c1193d6d97943e8c11cb25cb9658e81de28836fbfe53ac5bd33c1e1e494d945fe4cf2ee
|
|
@@ -41,8 +41,15 @@ module SpatialFeatures
|
|
|
41
41
|
update_spatial_cache(options.slice(:spatial_cache))
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# Attribute each warning to the file it came from (e.g. `archive.zip/layer.kml`)
|
|
45
|
+
# so a multi-file or multi-source import makes clear which file was affected.
|
|
46
|
+
import_warnings = imports.flat_map do |import|
|
|
47
|
+
import.warnings.map {|warning| [import.source_identifier.presence, warning].compact.join(': ') }
|
|
48
|
+
end
|
|
49
|
+
store_feature_update_warnings(import_warnings)
|
|
50
|
+
|
|
44
51
|
if imports.present? && features.compact_blank.empty? && !allow_blank
|
|
45
|
-
raise EmptyImportError, "No spatial features were found when updating"
|
|
52
|
+
raise EmptyImportError, ["No spatial features were found when updating.", *import_warnings].join(' ')
|
|
46
53
|
end
|
|
47
54
|
end
|
|
48
55
|
end
|
|
@@ -45,6 +45,30 @@ module SpatialFeatures
|
|
|
45
45
|
spatial_processing_status(:update_features!) == :failure
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
# Non-fatal messages from the most recent successful feature import (e.g. parts of
|
|
49
|
+
# the source that were skipped). Stored alongside the status cache so they survive
|
|
50
|
+
# job completion, since successful Delayed::Jobs are deleted and can't be read back.
|
|
51
|
+
WARNINGS_CACHE_KEY = 'feature_update_warnings'.freeze
|
|
52
|
+
|
|
53
|
+
def feature_update_warnings
|
|
54
|
+
return [] unless has_attribute?(:spatial_processing_status_cache)
|
|
55
|
+
Array(spatial_processing_status_cache[WARNINGS_CACHE_KEY])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def store_feature_update_warnings(warnings)
|
|
59
|
+
return unless has_attribute?(:spatial_processing_status_cache)
|
|
60
|
+
|
|
61
|
+
cache = spatial_processing_status_cache
|
|
62
|
+
warnings = Array(warnings).reject(&:blank?)
|
|
63
|
+
if warnings.present?
|
|
64
|
+
cache[WARNINGS_CACHE_KEY] = warnings
|
|
65
|
+
else
|
|
66
|
+
cache.delete(WARNINGS_CACHE_KEY)
|
|
67
|
+
end
|
|
68
|
+
self.spatial_processing_status_cache = cache
|
|
69
|
+
update_column(:spatial_processing_status_cache, cache) if persisted? && will_save_change_to_spatial_processing_status_cache?
|
|
70
|
+
end
|
|
71
|
+
|
|
48
72
|
def spatial_processing_status(method_name, use_cache: true)
|
|
49
73
|
if has_attribute?(:spatial_processing_status_cache)
|
|
50
74
|
update_spatial_processing_status(method_name) unless use_cache
|
|
@@ -4,12 +4,19 @@ module SpatialFeatures
|
|
|
4
4
|
module Importers
|
|
5
5
|
class Base
|
|
6
6
|
attr_reader :errors
|
|
7
|
+
|
|
8
|
+
# Non-fatal messages about parts of the source that could not be imported but
|
|
9
|
+
# did not prevent the remaining features from importing (e.g. unsupported
|
|
10
|
+
# elements). Unlike `errors`, warnings never abort the import.
|
|
11
|
+
attr_reader :warnings
|
|
12
|
+
|
|
7
13
|
attr_accessor :source_identifier # An identifier for the source of the features. Used to differentiate groups of features on the spatial model.
|
|
8
14
|
|
|
9
15
|
def initialize(data, make_valid: false, tmpdir: nil, source_identifier: nil, feature_name: ->(record) { record.name })
|
|
10
16
|
@make_valid = make_valid
|
|
11
17
|
@data = data
|
|
12
18
|
@errors = []
|
|
19
|
+
@warnings = []
|
|
13
20
|
@tmpdir = tmpdir
|
|
14
21
|
@source_identifier = source_identifier
|
|
15
22
|
@feature_name = feature_name
|
|
@@ -46,11 +46,28 @@ module SpatialFeatures
|
|
|
46
46
|
doc = Nokogiri::XML(@data)
|
|
47
47
|
doc.remove_namespaces! # We don't care about namespaces since the document is going to be filled with placemark geometry and we want it all without needing to deal with namespaces
|
|
48
48
|
raise ImportError, "Invalid KML document (root node was '#{doc.root&.name}')" unless doc.root&.name.to_s.casecmp?('kml')
|
|
49
|
-
|
|
49
|
+
discard_network_links(doc)
|
|
50
50
|
doc
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
# NetworkLinks reference geometry hosted elsewhere (e.g. a remote KMZ) rather
|
|
55
|
+
# than embedding it, so there is nothing for us to import from them. Rather than
|
|
56
|
+
# failing the whole file, we drop them and record a warning so any embedded
|
|
57
|
+
# geometry still imports and the user is told which layers were skipped. If the
|
|
58
|
+
# file contained nothing but NetworkLinks the import ends up empty and the
|
|
59
|
+
# EmptyImportError surfaces the warning as the reason.
|
|
60
|
+
def discard_network_links(doc)
|
|
61
|
+
network_links = doc.search('NetworkLink')
|
|
62
|
+
return if network_links.empty?
|
|
63
|
+
|
|
64
|
+
names = network_links.map {|link| link.at_css('name')&.text.presence }.compact.uniq
|
|
65
|
+
described = names.any? ? ": #{names.to_sentence}" : ''
|
|
66
|
+
@warnings << "Skipped #{network_links.size} network-linked #{'layer'.pluralize(network_links.size)} that reference remote data and cannot be imported#{described}."
|
|
67
|
+
|
|
68
|
+
network_links.remove
|
|
69
|
+
end
|
|
70
|
+
|
|
54
71
|
def blank_feature?(feature)
|
|
55
72
|
feature.css('coordinates').text.blank?
|
|
56
73
|
end
|