spatial_features 3.0.0 → 3.1.0

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: 6d3fe76f0ce82837de428e401ce4f6a20a84b97acb2085374a8bf8fe1daba5c8
4
- data.tar.gz: fed058553913c07b27838424dc07b1b63677f28798fae7d5534b55de7c1aa713
3
+ metadata.gz: 9578faf8d4205e8b25b7039b99df9ead3f03f13d82568277930c8824adb48980
4
+ data.tar.gz: 16a5be2783383686f570f598edd8ecf3da6350fb92d5b393618f8be919ab8c79
5
5
  SHA512:
6
- metadata.gz: 0f6aebd3553502127a91f68d5f692bd6311a8c7af0aca22bccc54cec712aa8371696b0f8e19c0c7aaffa9e98c1ee809d478612a5f7c2441452a202bc9f53280a
7
- data.tar.gz: fcf4f4eb0fc85f82ff726ec950936b9c45bdd9aaf85eb06067acac71b250185b6640e89f3536e5e5e1759b93efbee66e855460964ba112aa4f26a77cefae0abe
6
+ metadata.gz: 772ab77070751ca764ab8a06cf5260038be3cae8461c6e9c7fa894e644d2164cd8905281c43d0eab48b7ab2f06227b01da809687ec4ffb7bc1ade359c7097eea
7
+ data.tar.gz: da9f6d66e79f85362f4c6af9e3dc8400b4f6fb51bf0cb5ba84114ccb47b4541e59614d162271877c6d20d9d342fbc9a86b48de7e8a5a1de15b27c7136c09f3b3
data/README.md CHANGED
@@ -181,3 +181,18 @@ add_column :features, :tilegeom, :geometry
181
181
  add_index :features, :tilegeom, :using => :gist
182
182
  Feature.update_all('tilegeom = ST_Transform(geom, 3857)')
183
183
  ```
184
+
185
+ ## Testing
186
+
187
+ Create a postgres database:
188
+ ```bash
189
+ createdb spatial_features_test
190
+ ```
191
+
192
+ There are multiple gemfiles available for testing against different Rails versions. Set `BUNDLE_GEMFILE` to target them, e.g.
193
+
194
+ ```bash
195
+ bundle install
196
+ BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle install
197
+ BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle exec rspec
198
+ ```
@@ -1,4 +1,5 @@
1
1
  Mime::Type.register "application/vnd.geo+json", :geojson
2
+ Mime::Type.register "application/vnd.bounds+json", :bounds
2
3
  Mime::Type.register "application/vnd.mapbox-vector-tile", :mvt
3
4
  Mime::Type.register "application/vnd.google-earth.kml+xml", :kml
4
5
  Mime::Type.register "application/vnd.google-earth.kmz", :kmz
@@ -1,8 +1,12 @@
1
1
  module PostGISTypes
2
2
  def initialize_type_map(m = type_map)
3
3
  super
4
- register_class_with_limit m, 'geometry', ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::SpecializedString
5
- register_class_with_limit m, 'geography', ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::SpecializedString
4
+ %w[
5
+ geography
6
+ geometry
7
+ ].each do |geo_type|
8
+ m.register_type geo_type, ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::SpecializedString.new(geo_type.to_sym)
9
+ end
6
10
  end
7
11
  end
8
12
 
@@ -2,13 +2,6 @@ require 'open-uri'
2
2
 
3
3
  module SpatialFeatures
4
4
  module Download
5
- # file can be a url, path, or file, any of which can return be a zipped archive
6
- def self.read(file, unzip: nil, **unzip_options)
7
- file = Download.open_each(file, unzip: unzip, **unzip_options).first
8
- path = ::File.path(file)
9
- return ::File.read(path)
10
- end
11
-
12
5
  # file can be a url, path, or file, any of which can return be a zipped archive
13
6
  def self.open(file)
14
7
  file = Kernel.open(file)
@@ -1,4 +1,5 @@
1
1
  require 'digest/md5'
2
+ require 'fileutils'
2
3
 
3
4
  module SpatialFeatures
4
5
  module FeatureImport
@@ -21,9 +22,10 @@ module SpatialFeatures
21
22
 
22
23
  def update_features!(skip_invalid: false, **options)
23
24
  options = options.reverse_merge(spatial_features_options)
25
+ tmpdir = options.fetch(:tmpdir) { Dir.mktmpdir("ruby_spatial_features") }
24
26
 
25
27
  ActiveRecord::Base.transaction do
26
- imports = spatial_feature_imports(options[:import], options[:make_valid])
28
+ imports = spatial_feature_imports(options[:import], options[:make_valid], options[:tmpdir])
27
29
  cache_key = Digest::MD5.hexdigest(imports.collect(&:cache_key).join)
28
30
 
29
31
  return if features_cache_key_matches?(cache_key)
@@ -49,6 +51,8 @@ module SpatialFeatures
49
51
  else
50
52
  raise ImportError, e.message, e.backtrace
51
53
  end
54
+ ensure
55
+ FileUtils.remove_entry(tmpdir) if Dir.exist?(tmpdir)
52
56
  end
53
57
 
54
58
  def update_features_cache_key(cache_key)
@@ -73,10 +77,11 @@ module SpatialFeatures
73
77
 
74
78
  private
75
79
 
76
- def spatial_feature_imports(import_options, make_valid)
80
+ def spatial_feature_imports(import_options, make_valid, tmpdir)
77
81
  import_options.flat_map do |data_method, importer_name|
78
82
  Array.wrap(send(data_method)).flat_map do |data|
79
- spatial_importer_from_name(importer_name).create_all(data, :make_valid => make_valid) if data.present?
83
+ next unless data.present?
84
+ spatial_importer_from_name(importer_name).create_all(data, :make_valid => make_valid, :tmpdir => tmpdir)
80
85
  end
81
86
  end.compact
82
87
  end
@@ -56,7 +56,7 @@ module SpatialFeatures
56
56
  within_buffer(other, 0, options)
57
57
  end
58
58
 
59
- def within_buffer(other, buffer_in_meters = 0, **options)
59
+ def within_buffer(other, buffer_in_meters = 0, options = {})
60
60
  return none if other.is_a?(ActiveRecord::Base) && other.new_record?
61
61
 
62
62
  # Cache only works on single records, not scopes.
@@ -5,10 +5,11 @@ module SpatialFeatures
5
5
  class Base
6
6
  attr_reader :errors
7
7
 
8
- def initialize(data, make_valid: false)
8
+ def initialize(data, make_valid: false, tmpdir: nil)
9
9
  @make_valid = make_valid
10
10
  @data = data
11
11
  @errors = []
12
+ @tmpdir = tmpdir
12
13
  end
13
14
 
14
15
  def features
@@ -8,7 +8,7 @@ module SpatialFeatures
8
8
 
9
9
  FILE_PATTERNS = [/\.kml$/, /\.shp$/, /\.json$/, /\.geojson$/]
10
10
  def self.create_all(data, **options)
11
- Download.open_each(data, unzip: FILE_PATTERNS, downcase: true).map do |file|
11
+ Download.open_each(data, unzip: FILE_PATTERNS, downcase: true, tmpdir: options[:tmpdir]).map do |file|
12
12
  new(data, **options, current_file: file)
13
13
  end
14
14
  rescue Unzip::PathNotFound
@@ -23,7 +23,7 @@ module SpatialFeatures
23
23
  # If no `current_file` is passed then we just take the first valid file that we find.
24
24
  def initialize(data, *args, current_file: nil, **options)
25
25
  begin
26
- current_file ||= Download.open_each(data, unzip: FILE_PATTERNS, downcase: true).first
26
+ current_file ||= Download.open_each(data, unzip: FILE_PATTERNS, downcase: true, tmpdir: options[:tmpdir]).first
27
27
  rescue Unzip::PathNotFound
28
28
  raise ImportError, INVALID_ARCHIVE
29
29
  end
@@ -15,7 +15,7 @@ module SpatialFeatures
15
15
 
16
16
  def each_record(&block)
17
17
  {'Polygon' => 'POLYGON', 'LineString' => 'LINE', 'Point' => 'POINT'}.each do |kml_type, sql_type|
18
- Nokogiri::XML(@data).css(kml_type).each do |feature|
18
+ kml_document.css(kml_type).each do |feature|
19
19
  if placemark = feature.ancestors('Placemark').first
20
20
  name = placemark.css('name').text
21
21
  metadata = extract_metadata(placemark)
@@ -35,6 +35,14 @@ module SpatialFeatures
35
35
  end
36
36
  end
37
37
 
38
+ def kml_document
39
+ @kml_document ||= begin
40
+ doc = Nokogiri::XML(@data)
41
+ raise ImportError, "Invalid KML document (root node was '#{doc.root&.name}')" unless doc.root&.name.to_s.casecmp?('kml')
42
+ doc
43
+ end
44
+ end
45
+
38
46
  def blank_feature?(feature)
39
47
  feature.css('coordinates').text.blank?
40
48
  end
@@ -16,21 +16,19 @@ module SpatialFeatures
16
16
  return Array(paths)
17
17
  end
18
18
 
19
- def self.extract(file_path, output_dir = Dir.mktmpdir, downcase: false)
19
+ def self.extract(file_path, tmpdir: nil, downcase: false)
20
+ tmpdir ||= Dir.mktmpdir
20
21
  [].tap do |paths|
21
22
  entries(file_path).each do |entry|
22
23
  next if entry.name =~ IGNORED_ENTRY_PATHS
23
24
  output_filename = entry.name
24
25
  output_filename = output_filename.downcase if downcase
25
- path = "#{output_dir}/#{output_filename}"
26
+ path = "#{tmpdir}/#{output_filename}"
26
27
  FileUtils.mkdir_p(File.dirname(path))
27
28
  entry.extract(path)
28
29
  paths << path
29
30
  end
30
31
  end
31
- rescue => e
32
- FileUtils.remove_entry(output_dir)
33
- raise(e)
34
32
  end
35
33
 
36
34
  def self.names(file_path)
@@ -1,3 +1,3 @@
1
1
  module SpatialFeatures
2
- VERSION = "3.0.0"
2
+ VERSION = "3.1.0"
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: 3.0.0
4
+ version: 3.1.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: 2022-01-29 00:00:00.000000000 Z
12
+ date: 2022-05-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -17,20 +17,20 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '4.2'
20
+ version: '6'
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: '7.0'
23
+ version: '8'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
28
  - - ">="
29
29
  - !ruby/object:Gem::Version
30
- version: '4.2'
30
+ version: '6'
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: '7.0'
33
+ version: '8'
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: delayed_job_active_record
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -91,16 +91,16 @@ dependencies:
91
91
  name: nokogiri
92
92
  requirement: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '1.6'
96
+ version: '0'
97
97
  type: :runtime
98
98
  prerelease: false
99
99
  version_requirements: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '1.6'
103
+ version: '0'
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: pg
106
106
  requirement: !ruby/object:Gem::Requirement
@@ -129,6 +129,20 @@ dependencies:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
131
  version: '3.5'
132
+ - !ruby/object:Gem::Dependency
133
+ name: pry-byebug
134
+ requirement: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ type: :development
140
+ prerelease: false
141
+ version_requirements: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
132
146
  description: Adds spatial methods to a model.
133
147
  email:
134
148
  - contact@culturecode.ca
@@ -189,8 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
203
  - !ruby/object:Gem::Version
190
204
  version: '0'
191
205
  requirements: []
192
- rubyforge_project:
193
- rubygems_version: 2.7.6.3
206
+ rubygems_version: 3.0.3
194
207
  signing_key:
195
208
  specification_version: 4
196
209
  summary: Adds spatial methods to a model.