geo_concerns 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -2
  3. data/README.md +13 -0
  4. data/app/controllers/concerns/geo_concerns/file_sets_controller_behavior.rb +15 -0
  5. data/app/controllers/concerns/geo_concerns/geoblacklight_controller_behavior.rb +29 -0
  6. data/app/models/concerns/geo_concerns/ability.rb +12 -0
  7. data/app/models/concerns/geo_concerns/file_set/derivatives.rb +6 -6
  8. data/app/models/concerns/geo_concerns/geo_file_format_behavior.rb +4 -4
  9. data/app/presenters/geo_concerns/raster_work_show_presenter.rb +1 -1
  10. data/app/processors/geo_concerns/processors/mapnik.rb +30 -0
  11. data/app/processors/geo_concerns/processors/vector/base.rb +2 -1
  12. data/app/processors/geo_concerns/processors/vector/info.rb +66 -0
  13. data/app/services/geo_concerns/authority_service.rb +29 -0
  14. data/app/services/geo_concerns/discovery.rb +4 -0
  15. data/app/services/geo_concerns/discovery/abstract_document.rb +36 -0
  16. data/app/services/geo_concerns/discovery/document_builder.rb +69 -0
  17. data/app/services/geo_concerns/discovery/document_builder/basic_metadata_builder.rb +69 -0
  18. data/app/services/geo_concerns/discovery/document_builder/composite_builder.rb +21 -0
  19. data/app/services/geo_concerns/discovery/document_builder/date_builder.rb +38 -0
  20. data/app/services/geo_concerns/discovery/document_builder/document_helper.rb +10 -0
  21. data/app/services/geo_concerns/discovery/document_builder/document_path.rb +82 -0
  22. data/app/services/geo_concerns/discovery/document_builder/layer_info_builder.rb +65 -0
  23. data/app/services/geo_concerns/discovery/document_builder/references_builder.rb +82 -0
  24. data/app/services/geo_concerns/discovery/document_builder/spatial_builder.rb +40 -0
  25. data/app/services/geo_concerns/discovery/geoblacklight_document.rb +122 -0
  26. data/app/services/geo_concerns/image_format_service.rb +6 -0
  27. data/app/services/geo_concerns/metadata_format_service.rb +6 -0
  28. data/app/services/geo_concerns/raster_format_service.rb +6 -0
  29. data/app/services/geo_concerns/vector_format_service.rb +6 -0
  30. data/app/views/curation_concerns/image_works/show.html.erb +1 -1
  31. data/app/views/curation_concerns/raster_works/show.html.erb +1 -1
  32. data/app/views/curation_concerns/vector_works/show.html.erb +1 -1
  33. data/app/views/geo_concerns/_representative_media.html.erb +5 -0
  34. data/app/views/{curation_concerns → geo_concerns}/file_sets/_form.html.erb +4 -4
  35. data/app/views/geo_concerns/file_sets/media_display/_geo.html.erb +16 -0
  36. data/app/views/geo_concerns/file_sets/new.html.erb +12 -0
  37. data/config/routes.rb +18 -0
  38. data/geo_concerns.gemspec +2 -0
  39. data/lib/generators/geo_concerns/install_generator.rb +34 -0
  40. data/lib/generators/geo_concerns/templates/config/authorities/image_formats.yml +2 -0
  41. data/lib/generators/geo_concerns/templates/config/authorities/raster_formats.yml +4 -0
  42. data/lib/generators/geo_concerns/templates/config/authorities/vector_formats.yml +2 -0
  43. data/lib/generators/geo_concerns/templates/config/discovery/geoblacklight_schema.json +168 -0
  44. data/lib/generators/geo_concerns/templates/config/mapnik.yml +24 -0
  45. data/lib/generators/geo_concerns/templates/controllers/curation_concerns/image_works_controller.rb +1 -0
  46. data/lib/generators/geo_concerns/templates/controllers/curation_concerns/raster_works_controller.rb +1 -0
  47. data/lib/generators/geo_concerns/templates/controllers/curation_concerns/vector_works_controller.rb +1 -0
  48. data/lib/geo_concerns/version.rb +1 -1
  49. data/spec/controllers/file_sets_controller_spec.rb +20 -0
  50. data/spec/controllers/vector_works_controller_spec.rb +33 -0
  51. data/spec/processors/geo_concerns/processors/mapnik_spec.rb +48 -0
  52. data/spec/processors/geo_concerns/processors/vector/base_spec.rb +1 -1
  53. data/spec/processors/geo_concerns/processors/vector/info_spec.rb +41 -0
  54. data/spec/services/geo_concerns/discovery/abstract_document_spec.rb +23 -0
  55. data/spec/services/geo_concerns/discovery/document_builder_spec.rb +186 -0
  56. data/spec/services/geo_concerns/discovery/geoblacklight_document_spec.rb +17 -0
  57. data/spec/services/raster_format_service_spec.rb +1 -1
  58. data/template.rb +2 -2
  59. metadata +70 -9
  60. data/app/services/authority_service.rb +0 -23
  61. data/app/services/image_format_service.rb +0 -4
  62. data/app/services/metadata_format_service.rb +0 -4
  63. data/app/services/raster_format_service.rb +0 -4
  64. data/app/services/vector_format_service.rb +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5860cade4910404ebfc81e6d1dcb6524ab1b2a88
4
- data.tar.gz: cb1f2d4920984de204a0d04b06593c9d804abe02
3
+ metadata.gz: 11ccf6c23e362602390bfef2deccfa1a4db6bbf3
4
+ data.tar.gz: 9545ced09e1698ba1593290995281a664876e9be
5
5
  SHA512:
6
- metadata.gz: d04edc92c51d7de7f69fadec0b189e244a92586773715646efebb7076421301ff8c3ee97cd95fceeb1b9a903683968f51815e5120c4ce7d3b0d8058453cce79e
7
- data.tar.gz: b17861f0bc73e579ab4cf38614988c6909c033bbc66a03215399e0f6b71a360068ec8a39a53a4fb854c831707af2f654c8d765e58ff3e0051cbf4c70621de53c
6
+ metadata.gz: 1c56506cab52e2766131fd741694fd377bb6aba742415ac65f3431937220c14755258d03e0ee88e4bfbe14883ca894d28f0ed83e867c67c075938f7498ac39e6
7
+ data.tar.gz: 7d636601661854a5ac61772a5eb93e5925cca7cdccfa97c9adde6802f2d9fa54766075956712c64f7aaf76085e5230232bb61da2bd3598e7025744be6b2e3339
@@ -1,14 +1,21 @@
1
1
  language: ruby
2
- # cache: bundler
3
- sudo: false
2
+ sudo: true
4
3
  rvm:
5
4
  - 2.3.0
6
5
  env:
7
6
  global:
8
7
  - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
8
+ - MAPNIK_VERSION="2.3"
9
+ before_install:
10
+ - sudo apt-add-repository --yes ppa:mapnik/nightly-${MAPNIK_VERSION}
11
+ - sudo apt-get update -y
12
+ install:
13
+ - sudo apt-get -y install wget build-essential make libmapnik=${MAPNIK_VERSION}* mapnik-utils=${MAPNIK_VERSION}* libmapnik-dev=${MAPNIK_VERSION}* mapnik-input-plugin*=${MAPNIK_VERSION}*
9
14
  before_script:
10
15
  - jdk_switcher use oraclejdk8
11
16
  - gdalinfo --version
17
+ - gem install bundler -v 1.12.3
18
+ - bundle install
12
19
  services:
13
20
  - redis-server
14
21
  addons:
data/README.md CHANGED
@@ -20,6 +20,19 @@ Rails application for developing Hydra Geo models. Built around Curation Concern
20
20
  * You can install it on Mac OSX with `brew install gdal`.
21
21
  * On Ubuntu, use `sudo apt-get install gdal-bin`.
22
22
 
23
+ ## Mapnik
24
+
25
+ GeoConcerns requires that Mapnik 3.x or 2.x be installed at `/usr/local/lib/libmapnik.*`. For linux, a C++ compiler and build environment is also needed.
26
+
27
+ Mac OS X:
28
+
29
+ - https://github.com/mapnik/mapnik/wiki/MacInstallation or ```brew install mapnik```
30
+
31
+ Linux:
32
+
33
+ - https://github.com/mapnik/mapnik/wiki/LinuxInstallation
34
+ - Build environment: [gcc](https://help.ubuntu.com/community/InstallingCompilers) or clang
35
+
23
36
  ## Installation
24
37
 
25
38
  Create and run a new GeoConcerns application from a template:
@@ -6,6 +6,15 @@ module GeoConcerns
6
6
  self.form_class = CurationConcerns::Forms::FileSetEditForm
7
7
  end
8
8
 
9
+ # Render geo file sets form if parent is a geo work
10
+ def new
11
+ if geo?
12
+ render 'geo_concerns/file_sets/new'
13
+ else
14
+ super
15
+ end
16
+ end
17
+
9
18
  # inject mime_type into permitted params
10
19
  def file_set_params
11
20
  super.tap do |permitted_params|
@@ -16,5 +25,11 @@ module GeoConcerns
16
25
  def actor
17
26
  @actor ||= GeoConcerns::Actors::FileSetActor.new(@file_set, current_user)
18
27
  end
28
+
29
+ protected
30
+
31
+ def geo?
32
+ parent.image_work? || parent.raster_work? || parent.vector_work?
33
+ end
19
34
  end
20
35
  end
@@ -0,0 +1,29 @@
1
+ module GeoConcerns
2
+ module GeoblacklightControllerBehavior
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ def geoblacklight
7
+ respond_to do |f|
8
+ f.json do
9
+ if builder.to_hash.fetch(:error, nil)
10
+ render json: builder, status: 404
11
+ else
12
+ render json: builder
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def document_class
22
+ Discovery::GeoblacklightDocument
23
+ end
24
+
25
+ def builder
26
+ @builder ||= Discovery::DocumentBuilder.new(presenter, document_class.new)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ module GeoConcerns
2
+ module Ability
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ self.ability_logic += [:geo_concerns_permissions]
6
+ end
7
+
8
+ def geo_concerns_permissions
9
+ alias_action :geoblacklight, to: :read
10
+ end
11
+ end
12
+ end
@@ -5,11 +5,11 @@ module GeoConcerns
5
5
 
6
6
  def create_derivatives(filename)
7
7
  case geo_mime_type
8
- when *ImageFormatService.select_options.map(&:last)
8
+ when *GeoConcerns::ImageFormatService.select_options.map(&:last)
9
9
  image_derivatives(filename)
10
- when *RasterFormatService.select_options.map(&:last)
10
+ when *GeoConcerns::RasterFormatService.select_options.map(&:last)
11
11
  raster_derivatives(filename)
12
- when *VectorFormatService.select_options.map(&:last)
12
+ when *GeoConcerns::VectorFormatService.select_options.map(&:last)
13
13
  vector_derivatives(filename)
14
14
  end
15
15
 
@@ -19,7 +19,7 @@ module GeoConcerns
19
19
  def image_derivatives(filename)
20
20
  Hydra::Derivatives::ImageDerivatives
21
21
  .create(filename, outputs: [{ label: :thumbnail,
22
- format: 'jpg',
22
+ format: 'png',
23
23
  size: '200x150>',
24
24
  url: derivative_url('thumbnail') }])
25
25
  end
@@ -32,7 +32,7 @@ module GeoConcerns
32
32
  url: derivative_url('display_raster') },
33
33
  { input_format: geo_mime_type,
34
34
  label: :thumbnail,
35
- format: 'jpg',
35
+ format: 'png',
36
36
  size: '200x150',
37
37
  url: derivative_url('thumbnail') }])
38
38
  end
@@ -45,7 +45,7 @@ module GeoConcerns
45
45
  url: derivative_url('display_vector') },
46
46
  { input_format: geo_mime_type,
47
47
  label: :thumbnail,
48
- format: 'jpg',
48
+ format: 'png',
49
49
  size: '200x150',
50
50
  url: derivative_url('thumbnail') }])
51
51
  end
@@ -3,19 +3,19 @@ module GeoConcerns
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  def image_file?
6
- ImageFormatService.include?(geo_mime_type)
6
+ GeoConcerns::ImageFormatService.include?(geo_mime_type)
7
7
  end
8
8
 
9
9
  def raster_file?
10
- RasterFormatService.include?(geo_mime_type)
10
+ GeoConcerns::RasterFormatService.include?(geo_mime_type)
11
11
  end
12
12
 
13
13
  def vector_file?
14
- VectorFormatService.include?(geo_mime_type)
14
+ GeoConcerns::VectorFormatService.include?(geo_mime_type)
15
15
  end
16
16
 
17
17
  def external_metadata_file?
18
- MetadataFormatService.include?(geo_mime_type)
18
+ GeoConcerns::MetadataFormatService.include?(geo_mime_type)
19
19
  end
20
20
 
21
21
  def geo_file_format?
@@ -1,6 +1,6 @@
1
1
  module GeoConcerns
2
2
  class RasterWorkShowPresenter < GeoConcernsShowPresenter
3
3
  self.work_presenter_class = ::GeoConcerns::VectorWorkShowPresenter
4
- self.file_format_service = RasterFormatService
4
+ self.file_format_service = GeoConcerns::RasterFormatService
5
5
  end
6
6
  end
@@ -0,0 +1,30 @@
1
+ require 'simple_mapnik'
2
+
3
+ module GeoConcerns
4
+ module Processors
5
+ module Mapnik
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ def self.mapnik_vector_thumbnail(in_path, out_path, options)
10
+ vector_info = GeoConcerns::Processors::Vector::Info.new(in_path)
11
+ options[:name] = vector_info.name
12
+ SimpleMapnik.register_datasources '/usr/local/lib/mapnik/input'
13
+ map = SimpleMapnik::Map.new(*mapnik_size(options))
14
+ map.load_string(mapnik_config(in_path, options).xml)
15
+ map.zoom_all
16
+ map.to_file out_path
17
+ end
18
+
19
+ def self.mapnik_size(options)
20
+ options[:output_size].split(' ').map(&:to_i)
21
+ end
22
+
23
+ def self.mapnik_config(in_path, options)
24
+ path_name = "#{in_path}/#{options[:name]}"
25
+ SimpleMapnik::Config.new(path_name)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -6,6 +6,7 @@ module GeoConcerns
6
6
  include GeoConcerns::Processors::BaseGeoProcessor
7
7
  include GeoConcerns::Processors::Ogr
8
8
  include GeoConcerns::Processors::Gdal
9
+ include GeoConcerns::Processors::Mapnik
9
10
  include GeoConcerns::Processors::Zip
10
11
 
11
12
  def self.encode(path, options, output_file)
@@ -20,7 +21,7 @@ module GeoConcerns
20
21
  # Set of commands to run to encode the vector thumbnail.
21
22
  # @return [Array] set of command name symbols
22
23
  def self.encode_queue
23
- [:rasterize, :convert]
24
+ [:reproject, :mapnik_vector_thumbnail]
24
25
  end
25
26
 
26
27
  # Set of commands to run to reproject the vector.
@@ -0,0 +1,66 @@
1
+ module GeoConcerns
2
+ module Processors
3
+ module Vector
4
+ class Info
5
+ attr_accessor :doc
6
+ attr_writer :name, :driver
7
+
8
+ def initialize(path)
9
+ @doc = ogrinfo(path)
10
+ end
11
+
12
+ # Returns the vector dataset name
13
+ # @return [String] dataset name
14
+ def name
15
+ @name = vector_name
16
+ end
17
+
18
+ # Returns the ogr driver name
19
+ # @return [String] driver name
20
+ def driver
21
+ @driver = driver_name
22
+ end
23
+
24
+ # Returns vector geometry type
25
+ # @return [String] geom
26
+ def geom
27
+ @geom = vector_geom
28
+ end
29
+
30
+ private
31
+
32
+ # Runs the ogrinfo command and returns the result as a string.
33
+ # @param path [String] path to vector file or shapefile directory
34
+ # @return [String] output of ogrinfo
35
+ def ogrinfo(path)
36
+ stdout, _stderr, _status = Open3.capture3("ogrinfo #{path}")
37
+ stdout
38
+ end
39
+
40
+ # Given an output string from the ogrinfo command, returns
41
+ # the vector dataset name.
42
+ # @return [String] vector dataset name
43
+ def vector_name
44
+ match = /(?<=\d:\s).*?((?=\s)|($))/.match(doc)
45
+ match ? match[0] : ''
46
+ end
47
+
48
+ # Given an output string from the ogrinfo command, returns
49
+ # the ogr driver used to read dataset.
50
+ # @return [String] ogr driver name
51
+ def driver_name
52
+ match = /(?<=driver\s`).*?(?=')/.match(doc)
53
+ match ? match[0] : ''
54
+ end
55
+
56
+ # Given an output string from the ogrinfo command, returns
57
+ # the vector geometry type.
58
+ # @return [String] vector geom
59
+ def vector_geom
60
+ match = /(?<=\().*?(?=\))/.match(doc)
61
+ match ? match[0] : ''
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,29 @@
1
+ module GeoConcerns
2
+ module AuthorityService
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ mattr_accessor :authority
7
+ end
8
+
9
+ class_methods do
10
+ def select_options
11
+ authority.all.map do |element|
12
+ [element[:label], element[:id]]
13
+ end
14
+ end
15
+
16
+ def label(id)
17
+ (authority.find(id) || {}).fetch('term', nil)
18
+ end
19
+
20
+ def code(id)
21
+ (authority.find(id) || {}).fetch('code', nil)
22
+ end
23
+
24
+ def include?(id)
25
+ !authority.find(id).nil? && !authority.find(id).empty?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ module GeoConcerns
2
+ module Discovery
3
+ end
4
+ end
@@ -0,0 +1,36 @@
1
+ module GeoConcerns
2
+ module Discovery
3
+ class AbstractDocument
4
+ attr_accessor :id, :provenance, :creator, :subject, :spatial, :temporal,
5
+ :title, :identifier, :description, :access_rights, :language,
6
+ :publisher, :slug, :solr_coverage, :geo_rss_coverage, :layer_year,
7
+ :date_modified, :geom_type, :format, :resource_type, :wxs_identifier,
8
+ :dct_references, :fgdc, :iso19139, :mods, :download, :url, :thumbnail
9
+
10
+ # Cleans the document hash by removing unused fields.
11
+ # @param [Hash] document hash
12
+ # @return [Hash] cleaned document hash
13
+ def clean_document(hash)
14
+ hash.delete_if do |_k, v|
15
+ begin
16
+ v.nil? || v.empty?
17
+ rescue
18
+ false
19
+ end
20
+ end
21
+ end
22
+
23
+ def to_hash(_arg)
24
+ raise 'this method should be overriden and return the document as a hash'
25
+ end
26
+
27
+ def to_json(_arg)
28
+ raise 'this method should be overriden and return the document as json'
29
+ end
30
+
31
+ def to_xml(_arg)
32
+ raise 'this method should be overriden and return the document as xml'
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,69 @@
1
+ module GeoConcerns
2
+ module Discovery
3
+ class DocumentBuilder
4
+ attr_reader :geo_concern, :document
5
+ delegate :to_json, :to_xml, :to_hash, to: :document
6
+
7
+ def initialize(geo_concern, document, ssl: false)
8
+ @geo_concern = geo_concern
9
+ @document = document
10
+ @ssl = ssl
11
+ builders.build(document)
12
+ end
13
+
14
+ # Returns a document path object. Used to get urls for links in the document.
15
+ # @return [DocumentPath] geoblacklight document as a json string
16
+ def root_path
17
+ @root_path ||= DocumentPath.new(geo_concern, ssl: @ssl)
18
+ end
19
+
20
+ # Instantiates a CompositeBuilder object with an array of
21
+ # builder instances that are used to create the document.
22
+ # @return [CompositeBuilder] composite builder for document
23
+ def builders
24
+ @builders ||= CompositeBuilder.new(
25
+ basic_metadata_builder,
26
+ spatial_builder,
27
+ date_builder,
28
+ references_builder,
29
+ layer_info_builder
30
+ )
31
+ end
32
+
33
+ # Instantiates a BasicMetadataBuilder object.
34
+ # Builds fields such as id, subject, and publisher.
35
+ # @return [BasicMetadataBuilder] basic metadata builder for document
36
+ def basic_metadata_builder
37
+ BasicMetadataBuilder.new(geo_concern)
38
+ end
39
+
40
+ # Instantiates a SpatialBuilder object.
41
+ # Builds spatial fields such as bounding box and solr geometry.
42
+ # @return [SpatialBuilder] spatial builder for document
43
+ def spatial_builder
44
+ SpatialBuilder.new(geo_concern)
45
+ end
46
+
47
+ # Instantiates a DateBuilder object.
48
+ # Builds date fields such as layer year and modified date.
49
+ # @return [DateBuilder] date builder for document
50
+ def date_builder
51
+ DateBuilder.new(geo_concern)
52
+ end
53
+
54
+ # Instantiates a ReferencesBuilder object.
55
+ # Builds service reference fields such as thumbnail and download url.
56
+ # @return [ReferencesBuilder] references builder for document
57
+ def references_builder
58
+ ReferencesBuilder.new(geo_concern, root_path)
59
+ end
60
+
61
+ # Instantiates a LayerInfoBuilder object.
62
+ # Builds fields about the geospatial file such as geometry and format.
63
+ # @return [LayerInfoBuilder] layer info builder for document
64
+ def layer_info_builder
65
+ LayerInfoBuilder.new(geo_concern)
66
+ end
67
+ end
68
+ end
69
+ end