Class: SpatialFeatures::Importers::File

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/spatial_features/importers/file.rb

Constant Summary collapse

INVALID_ARCHIVE =
"This file doesn't contain any map data.".freeze
SUPPORTED_FORMATS =
"Please upload a KMZ, KML, zipped ArcGIS shapefile, ESRI JSON, or GeoJSON file.".freeze
FILE_PATTERNS =
[/\.kml$/, /\.shp$/, /\.json$/, /\.geojson$/]

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, current_file: nil, **options) ⇒ File

The File importer may be initialized multiple times by ::create_all if it receives ZIP data containing multiple KML or SHP files. We use current_file to distinguish which file in the archive is currently being processed.

If no current_file is passed then we just take the first valid file that we find.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/spatial_features/importers/file.rb', line 35

def initialize(data, current_file: nil, **options)
  begin
    @current_file = current_file || Download.open_each(data, unzip: FILE_PATTERNS, downcase: true, tmpdir: options[:tmpdir]).first
  rescue Unzip::PathNotFound => e
    raise ImportError, self.class.invalid_archive_message(e)
  end

  case ::File.extname(data).downcase
  when '.kmz' # KMZ always has a single kml in it, so no need to show mention it
    options[:source_identifier] = ::File.basename(data)
  else
    options[:source_identifier] = [::File.basename(data), ::File.basename(@current_file.path)].uniq.join('/')
  end

  case ::File.extname(filename)
  when '.kml'
    __setobj__(KMLFile.new(@current_file, **options))
  when '.shp'
    __setobj__(Shapefile.new(@current_file, **options))
  when '.json', '.geojson'
    __setobj__(ESRIGeoJSON.new(@current_file.path, **options))
  else
    import_error!
  end
end

Class Method Details

.create_all(data, **options) ⇒ Object



10
11
12
13
14
15
16
# File 'lib/spatial_features/importers/file.rb', line 10

def self.create_all(data, **options)
  Download.open_each(data, unzip: FILE_PATTERNS, downcase: true, tmpdir: options[:tmpdir]).map do |file|
    new(data, **options, current_file: file)
  end
rescue Unzip::PathNotFound => e
  raise ImportError, invalid_archive_message(e)
end

.invalid_archive_message(path_not_found) ⇒ Object

Name what the archive held instead of only what we needed — a submitter who is told their upload contains PDFs knows immediately that they attached the wrong file, where "did not contain a .shp" leaves them guessing.



21
22
23
24
25
26
27
# File 'lib/spatial_features/importers/file.rb', line 21

def self.invalid_archive_message(path_not_found)
  found = path_not_found.extensions
  count = path_not_found.paths.count {|path| !path.end_with?('/') }
  contents = " It contains #{count} #{found.to_sentence} #{'file'.pluralize(count)}." if found.any?

  [INVALID_ARCHIVE, contents, " ", SUPPORTED_FORMATS].compact.join
end