spatial_features 3.12.0 → 3.13.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 992823b144d43f8a6c13f32ce0fbd71bb6bea5bafb1aadb7840767f18d2a8d9f
4
- data.tar.gz: 45397ed799db69896d94a48e8c3958ab7026420587e9dd1a4755fe57a650132f
3
+ metadata.gz: 3b36a07cd400459369dcdaedd71899954e1a4687d94db1ac1d62e987a17c9552
4
+ data.tar.gz: '02101805b5ad1fee94e726fde4c24bba09e79641cc575361ff25ff51779f0fbc'
5
5
  SHA512:
6
- metadata.gz: 9a9c533b9af654d339344dee13b62f14becf6e2c20fdd57868bfe5c185a5bede4657d130a6c9049d0557b274c1ed2a4a7cd70a8b826c3548824ed4b7bf7df76c
7
- data.tar.gz: 7a9d9ecdd4f65b01e2cc3c0558ca3699205ecf783617e2adcd4958ca2639dd8240a99b883f1567199ce34ca5a3aad4d5bee4804902c9dddc3cf7e38690015fa5
6
+ metadata.gz: 3bf6e8b22a387558f09ec940d080403535ecfe89c178b8ddb3233f1d55c8107e312d6cd0f3300d43176f52d06fa41f4f490d7dc0a4c1fb3131268fdd5a3a7185
7
+ data.tar.gz: ef898f88ad2b999c4d363312ae6527e5cd05ba4e7a14ef8f43330862da8e6e9a73b48515ad21ab3539aa267d87bdded6d4817630a95edf2b7832c3b844e369b8
@@ -34,17 +34,19 @@ module SpatialFeatures
34
34
  fetch(path_or_url).read
35
35
  end
36
36
 
37
- # Returns an open File for each source in `path_or_url`, unwrapping an archive when
37
+ # Returns an open file for each source in `path_or_url`, unwrapping an archive when
38
38
  # `unzip` is given a pattern its entries can match.
39
+ #
40
+ # @note A remote or IO-backed source is held in a `Tempfile`, which unlinks its path
41
+ # when it is garbage collected. The `Tempfile` itself is returned, rather than a fresh
42
+ # `File` opened on its path, so the path stays valid for as long as the caller holds
43
+ # the result. Entries extracted from an archive are ordinary files on disk and are
44
+ # opened by path.
39
45
  def open_each(path_or_url, unzip: nil, **unzip_options)
40
46
  file = Download.open(path_or_url)
41
- files = if unzip && Unzip.is_zip?(file)
42
- find_in_zip(file, find: unzip, **unzip_options)
43
- else
44
- [file]
45
- end
47
+ return [file] unless unzip && Unzip.is_zip?(file)
46
48
 
47
- return files.map { |f| File.open(f) }
49
+ find_in_zip(file, find: unzip, **unzip_options).map { |path| File.open(path) }
48
50
  end
49
51
 
50
52
  def normalize_file(file)
@@ -0,0 +1,62 @@
1
+ require 'exifr/jpeg'
2
+ require 'ostruct'
3
+
4
+ module SpatialFeatures
5
+ module Importers
6
+ class ExifPhoto < Base
7
+ JPEG_PATTERN = /\.jpe?g\z/i.freeze
8
+ NO_PHOTOS = "This archive doesn't contain any JPEG photos.".freeze
9
+ UNREADABLE_PHOTO = "This photo couldn't be read. It may be damaged, or saved in a JPEG format we don't support.".freeze
10
+
11
+ def self.create_all(data, **options)
12
+ Download.open_each(data, unzip: JPEG_PATTERN, tmpdir: options[:tmpdir]).map do |file|
13
+ new(file.path, **options)
14
+ end
15
+ rescue Unzip::PathNotFound
16
+ raise ImportError, NO_PHOTOS
17
+ end
18
+
19
+ def initialize(data, **options)
20
+ options[:source_identifier] ||= ::File.basename(data.to_s)
21
+ super(data, **options)
22
+ end
23
+
24
+ def cache_key
25
+ @cache_key ||= Digest::MD5.file(@data).hexdigest
26
+ end
27
+
28
+ private
29
+
30
+ def each_record
31
+ photo = EXIFR::JPEG.new(@data)
32
+ gps = photo.gps
33
+ unless usable_gps?(gps)
34
+ @warnings << 'No usable GPS coordinates were found in this photo.'
35
+ return
36
+ end
37
+
38
+ yield OpenStruct.new(
39
+ name: ::File.basename(@data),
40
+ geog: "POINT(#{gps.longitude} #{gps.latitude})",
41
+ metadata: metadata_from(photo, gps),
42
+ importable_image_paths: [@data]
43
+ )
44
+ rescue EXIFR::MalformedImage
45
+ raise ImportError, UNREADABLE_PHOTO
46
+ end
47
+
48
+ def usable_gps?(gps)
49
+ gps && gps.latitude.is_a?(Numeric) && gps.longitude.is_a?(Numeric) &&
50
+ (-90..90).cover?(gps.latitude) && (-180..180).cover?(gps.longitude)
51
+ end
52
+
53
+ def metadata_from(photo, gps)
54
+ {
55
+ 'capture_time' => photo.date_time_original&.strftime('%Y-%m-%d %H:%M:%S'),
56
+ 'altitude' => gps.altitude&.to_s,
57
+ 'camera_model' => photo.model.presence
58
+ }.compact
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,3 +1,3 @@
1
1
  module SpatialFeatures
2
- VERSION = "3.12.0"
2
+ VERSION = "3.13.0"
3
3
  end
@@ -21,6 +21,7 @@ require 'spatial_features/has_spatial_features/queued_spatial_processing'
21
21
  require 'spatial_features/has_spatial_features/feature_import'
22
22
 
23
23
  require 'spatial_features/importers/base'
24
+ require 'spatial_features/importers/exif_photo'
24
25
  require 'spatial_features/importers/file'
25
26
  require 'spatial_features/importers/geo_json'
26
27
  require 'spatial_features/importers/esri_geo_json'
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.12.0
4
+ version: 3.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Wallace
@@ -114,6 +114,20 @@ dependencies:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: exifr
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
117
131
  - !ruby/object:Gem::Dependency
118
132
  name: rails
119
133
  requirement: !ruby/object:Gem::Requirement
@@ -204,6 +218,7 @@ files:
204
218
  - lib/spatial_features/has_spatial_features/queued_spatial_processing.rb
205
219
  - lib/spatial_features/importers/base.rb
206
220
  - lib/spatial_features/importers/esri_geo_json.rb
221
+ - lib/spatial_features/importers/exif_photo.rb
207
222
  - lib/spatial_features/importers/file.rb
208
223
  - lib/spatial_features/importers/geo_json.rb
209
224
  - lib/spatial_features/importers/geomark.rb