spatial_features 2.19.1 → 2.20.0
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/README.md +10 -1
- data/app/models/feature.rb +2 -0
- data/lib/spatial_features/has_spatial_features/feature_import.rb +19 -2
- data/lib/spatial_features/importers/base.rb +2 -1
- data/lib/spatial_features/importers/kml.rb +30 -3
- data/lib/spatial_features/importers/kml_file.rb +7 -3
- data/lib/spatial_features/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 639dee46fedd2cf507642b41119ff99e93506b54d891ab42d21a1f24fcf5a679
|
4
|
+
data.tar.gz: 956175227c6a59acc867810a51796303218eac70c9bc49fe0d0f8222ea8558e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a1ac7a0dca15400e0e03f0f1c2192e22a4c1e818edde2a832f925e6ee803a9284c5236684228e25dbeabf2d147aacef4f4c05170216b0857941c87ed9b9a395
|
7
|
+
data.tar.gz: da6fc8be7449202dfe46de18f0829e49664626ba17b90b6e3c1eae7a059f38a10d8310046e4f2bf44fb80bf78f2cdeea26624f429fc0d7b5873775b332086712
|
data/README.md
CHANGED
@@ -109,8 +109,17 @@ Person.new(:features => [Feature.new(:geog => 'some binary PostGIS Geography str
|
|
109
109
|
You can specify multiple import sources for geometry. Each key is a method that returns the data for the Importer, and
|
110
110
|
each value is the Importer to use to parse the data. See each Importer for more details.
|
111
111
|
```ruby
|
112
|
+
def ImageImporter
|
113
|
+
def self.call(feature, image_paths)
|
114
|
+
image_paths.each do |pathname|
|
115
|
+
# ...
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
112
120
|
class Location < ActiveRecord::Base
|
113
|
-
has_spatial_features :import => { :remote_kml_url => 'KMLFile', :file => 'File', :geojson => 'GeoJSON' }
|
121
|
+
has_spatial_features :import => { :remote_kml_url => 'KMLFile', :file => 'File', :geojson => 'GeoJSON' },
|
122
|
+
:image_handlers => ['ImageImporter']
|
114
123
|
|
115
124
|
def remote_kml_url
|
116
125
|
"www.test.com/kml/#{id}.kml"
|
data/app/models/feature.rb
CHANGED
@@ -15,6 +15,8 @@ class Feature < AbstractFeature
|
|
15
15
|
|
16
16
|
after_save :refresh_aggregate, if: :automatically_refresh_aggregate?
|
17
17
|
|
18
|
+
attr_accessor :importable_image_paths # :nodoc:
|
19
|
+
|
18
20
|
# Features are used for display so we also cache their KML representation
|
19
21
|
def self.cache_derivatives(options = {})
|
20
22
|
super
|
@@ -8,7 +8,7 @@ module SpatialFeatures
|
|
8
8
|
included do
|
9
9
|
extend ActiveModel::Callbacks
|
10
10
|
define_model_callbacks :update_features
|
11
|
-
spatial_features_options.reverse_merge!(:import => {}, spatial_cache: [])
|
11
|
+
spatial_features_options.reverse_merge!(:import => {}, :spatial_cache => [], :image_handlers => [])
|
12
12
|
end
|
13
13
|
|
14
14
|
module ClassMethods
|
@@ -78,13 +78,30 @@ module SpatialFeatures
|
|
78
78
|
"SpatialFeatures::Importers::#{importer_name}".constantize
|
79
79
|
end
|
80
80
|
|
81
|
+
def handle_images(feature)
|
82
|
+
return if feature.importable_image_paths.nil? || feature.importable_image_paths.empty?
|
83
|
+
|
84
|
+
Array(spatial_features_options[:image_handlers]).each do |image_handler|
|
85
|
+
image_handler_from_name(image_handler).call(feature, feature.importable_image_paths)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def image_handler_from_name(handler_name)
|
90
|
+
handler_name.to_s.constantize
|
91
|
+
end
|
92
|
+
|
81
93
|
def import_features(imports, skip_invalid)
|
82
94
|
features.delete_all
|
83
95
|
valid, invalid = Feature.defer_aggregate_refresh do
|
84
96
|
Feature.without_caching_derivatives do
|
85
97
|
imports.flat_map(&:features).partition do |feature|
|
86
98
|
feature.spatial_model = self
|
87
|
-
feature.save
|
99
|
+
if feature.save
|
100
|
+
handle_images(feature)
|
101
|
+
true
|
102
|
+
else
|
103
|
+
false
|
104
|
+
end
|
88
105
|
end
|
89
106
|
end
|
90
107
|
end
|
@@ -46,7 +46,8 @@ module SpatialFeatures
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def build_feature(record)
|
49
|
-
|
49
|
+
importable_image_paths = record.importable_image_paths if record.respond_to?(:importable_image_paths)
|
50
|
+
Feature.new(:name => record.name, :metadata => record.metadata, :feature_type => record.feature_type, :geog => record.geog, :importable_image_paths => importable_image_paths, :make_valid => @make_valid)
|
50
51
|
end
|
51
52
|
end
|
52
53
|
end
|
@@ -3,6 +3,14 @@ require 'ostruct'
|
|
3
3
|
module SpatialFeatures
|
4
4
|
module Importers
|
5
5
|
class KML < Base
|
6
|
+
# <SimpleData name> keys that may contain <img> tags
|
7
|
+
IMAGE_METADATA_KEYS = %w[pdfmaps_photos].freeze
|
8
|
+
|
9
|
+
def initialize(data, base_dir: nil, **args)
|
10
|
+
@base_dir = base_dir
|
11
|
+
super data, **args
|
12
|
+
end
|
13
|
+
|
6
14
|
private
|
7
15
|
|
8
16
|
def each_record(&block)
|
@@ -18,10 +26,11 @@ module SpatialFeatures
|
|
18
26
|
next if blank_feature?(feature)
|
19
27
|
|
20
28
|
geog = geom_from_kml(feature)
|
21
|
-
|
22
29
|
next if geog.blank?
|
23
30
|
|
24
|
-
|
31
|
+
importable_image_paths = images_from_metadata(metadata)
|
32
|
+
|
33
|
+
yield OpenStruct.new(:feature_type => sql_type, :geog => geog, :name => name, :metadata => metadata, :importable_image_paths => importable_image_paths)
|
25
34
|
end
|
26
35
|
end
|
27
36
|
end
|
@@ -32,17 +41,35 @@ module SpatialFeatures
|
|
32
41
|
|
33
42
|
def geom_from_kml(kml)
|
34
43
|
geom = nil
|
44
|
+
conn = nil
|
35
45
|
|
36
46
|
# Do query in a new thread so we use a new connection (if the query fails it will poison the transaction of the current connection)
|
47
|
+
#
|
48
|
+
# We manually checkout a new connection since Rails re-uses DB connections across threads.
|
37
49
|
Thread.new do
|
38
|
-
|
50
|
+
conn = ActiveRecord::Base.connection_pool.checkout
|
51
|
+
geom = conn.select_value("SELECT ST_GeomFromKML(#{conn.quote(kml.to_s)})")
|
39
52
|
rescue ActiveRecord::StatementInvalid => e # Discard Invalid KML features
|
40
53
|
geom = nil
|
54
|
+
ensure
|
55
|
+
ActiveRecord::Base.connection_pool.checkin(conn) if conn
|
41
56
|
end.join
|
42
57
|
|
43
58
|
return geom
|
44
59
|
end
|
45
60
|
|
61
|
+
def images_from_metadata(metadata)
|
62
|
+
IMAGE_METADATA_KEYS.flat_map do |key|
|
63
|
+
images = metadata.delete(key)
|
64
|
+
next unless images
|
65
|
+
|
66
|
+
Nokogiri::HTML.fragment(images).css("img").map do |img|
|
67
|
+
next unless (src = img["src"])
|
68
|
+
@base_dir.join(src.downcase)
|
69
|
+
end
|
70
|
+
end.compact
|
71
|
+
end
|
72
|
+
|
46
73
|
def extract_metadata(placemark)
|
47
74
|
metadata = {}
|
48
75
|
metadata.merge! extract_table(placemark)
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module SpatialFeatures
|
2
2
|
module Importers
|
3
3
|
class KMLFile < KML
|
4
|
-
def initialize(path_or_url,
|
5
|
-
|
6
|
-
|
4
|
+
def initialize(path_or_url, **options)
|
5
|
+
path = Download.open_each(path_or_url, unzip: [/\.kml$/], downcase: true).first
|
6
|
+
super ::File.read(path), base_dir: Pathname.new(path).dirname, **options
|
7
7
|
rescue SocketError, Errno::ECONNREFUSED, OpenURI::HTTPError
|
8
8
|
url = URI(path_or_url)
|
9
9
|
raise ImportError, "KML server is not responding. Ensure server is running and accessible at #{[url.scheme, "//#{url.host}", url.port].select(&:present?).join(':')}."
|
10
10
|
end
|
11
|
+
|
12
|
+
def cache_key
|
13
|
+
@cache_key ||= Digest::MD5.hexdigest(@data)
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
13
17
|
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.
|
4
|
+
version: 2.20.0
|
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: 2021-12-
|
12
|
+
date: 2021-12-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -175,8 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
175
|
- !ruby/object:Gem::Version
|
176
176
|
version: '0'
|
177
177
|
requirements: []
|
178
|
-
|
179
|
-
rubygems_version: 2.7.6.3
|
178
|
+
rubygems_version: 3.0.3
|
180
179
|
signing_key:
|
181
180
|
specification_version: 4
|
182
181
|
summary: Adds spatial methods to a model.
|