diff --git a/lib/avm/controlled_vocabulary.rb b/lib/avm/controlled_vocabulary.rb
new file mode 100644
index 0000000..cb11428
--- /dev/null
+++ b/lib/avm/controlled_vocabulary.rb
@@ -0,0 +1,18 @@
+module AVM
+ module ControlledVocabulary
+ class << self
+ def included(klass)
+ klass::TERMS.each do |type|
+ new_klass = Class.new do
+ def to_s
+ self.class.to_s.split('::').last
+ end
+ end
+
+ klass.const_set(type.to_sym, new_klass)
+ end
+ end
+ end
+ end
+end
+
diff --git a/lib/avm/coordinate_frame.rb b/lib/avm/coordinate_frame.rb
new file mode 100644
index 0000000..376f94b
--- /dev/null
+++ b/lib/avm/coordinate_frame.rb
@@ -0,0 +1,10 @@
+require 'avm/controlled_vocabulary'
+
+module AVM
+ module CoordinateFrame
+ TERMS = %w{ICRS FK5 FK4 ECL GAL SGAL}
+
+ include ControlledVocabulary
+ end
+end
+
diff --git a/lib/avm/coordinate_system_projection.rb b/lib/avm/coordinate_system_projection.rb
new file mode 100644
index 0000000..217134c
--- /dev/null
+++ b/lib/avm/coordinate_system_projection.rb
@@ -0,0 +1,10 @@
+require 'avm/controlled_vocabulary'
+
+module AVM
+ module CoordinateSystemProjection
+ TERMS = %w{TAN SIN ARC AIT CAR CEA}
+
+ include ControlledVocabulary
+ end
+end
+
diff --git a/lib/avm/image.rb b/lib/avm/image.rb
index 112e285..0aa66c9 100644
--- a/lib/avm/image.rb
+++ b/lib/avm/image.rb
@@ -2,6 +2,9 @@ require 'avm/creator'
require 'avm/xmp'
require 'avm/image_type'
require 'avm/image_quality'
+require 'avm/spatial_quality'
+require 'avm/coordinate_system_projection'
+require 'avm/coordinate_frame'
require 'avm/observation'
module AVM
@@ -16,7 +19,20 @@ module AVM
'Date',
'ID',
'Type',
- 'Image.ProductQuality'
+ 'Image.ProductQuality',
+ 'Spatial.Equinox',
+ 'Spatial.Rotation',
+ 'Spatial.Notes',
+ 'Spatial.FITSheader',
+ 'Spatial.Quality',
+ 'Spatial.CoordsystemProjection',
+ 'Spatial.CDMatrix',
+ 'Spatial.Scale',
+ 'Spatial.ReferencePixel',
+ 'Spatial.ReferenceDimension',
+ 'Spatial.ReferenceValue',
+ 'Spatial.Equinox',
+ 'Spatial.CoordinateFrame'
]
AVM_SINGLE_METHODS = [
@@ -27,7 +43,20 @@ module AVM
:date,
:id,
:type,
- :quality
+ :quality,
+ :spatial_equinox,
+ :spatial_rotation,
+ :spatial_notes,
+ :fits_header,
+ :spatial_quality,
+ :coordinate_system_projection,
+ :spatial_cd_matrix,
+ :spatial_scale,
+ :reference_pixel,
+ :reference_dimension,
+ :reference_value,
+ :equinox,
+ :coordinate_frame
]
AVM_SINGLE_MESSAGES = [
@@ -38,16 +67,50 @@ module AVM
:string_date,
:id,
:image_type,
- :image_quality
+ :image_quality,
+ :spatial_equinox,
+ :spatial_rotation,
+ :spatial_notes,
+ :fits_header,
+ :spatial_quality,
+ :coordinate_system_projection,
+ :spatial_cd_matrix,
+ :spatial_scale,
+ :reference_pixel,
+ :reference_dimension,
+ :reference_value,
+ :equinox,
+ :coordinate_frame
]
AVM_SINGLES = AVM_SINGLE_FIELDS.zip(AVM_SINGLE_METHODS)
+ AVM_TO_FLOAT = [
+ :spatial_rotation,
+ :spatial_cd_matrix,
+ :spatial_scale,
+ :reference_pixel,
+ :reference_dimension,
+ :reference_value
+ ]
+
attr_reader :creator, :observations
def initialize(options = {})
@creator = AVM::Creator.new(self)
@options = options
+
+ AVM_TO_FLOAT.each do |field|
+ if @options[field]
+ case @options[field]
+ when Array
+ @options[field].collect!(&:to_f)
+ else
+ @options[field] = @options[field].to_f
+ end
+ end
+ end
+
@observations = []
end
@@ -95,11 +158,23 @@ module AVM
end
def image_type
- (AVM::ImageType.const_get(@options[:type].to_sym).new rescue nil)
+ cv_class_instance_for(AVM::ImageType, :type)
end
def image_quality
- (AVM::ImageQuality.const_get(@options[:quality].to_sym).new rescue nil)
+ cv_class_instance_for(AVM::ImageQuality, :quality)
+ end
+
+ def spatial_quality
+ cv_class_instance_for(AVM::SpatialQuality, :spatial_quality)
+ end
+
+ def coordinate_frame
+ cv_class_instance_for(AVM::CoordinateFrame, :coordinate_frame)
+ end
+
+ def coordinate_system_projection
+ cv_class_instance_for(AVM::CoordinateSystemProjection, :coordinate_system_projection)
end
def date
@@ -129,7 +204,11 @@ module AVM
AVM_SINGLES.each do |tag, field|
if node = refs[:avm].at_xpath("./avm:#{tag}")
- options[field] = node.text
+ if !(list_items = node.search('.//rdf:li')).empty?
+ options[field] = list_items.collect(&:text)
+ else
+ options[field] = node.text
+ end
end
end
@@ -168,6 +247,10 @@ module AVM
def rdf_li(text)
%{#{text}}
end
+
+ def cv_class_instance_for(mod, field)
+ (mod.const_get(@options[field].to_sym).new rescue nil)
+ end
end
end
diff --git a/lib/avm/image_quality.rb b/lib/avm/image_quality.rb
index ca1a7d9..c664d13 100644
--- a/lib/avm/image_quality.rb
+++ b/lib/avm/image_quality.rb
@@ -1,14 +1,10 @@
+require 'avm/controlled_vocabulary'
+
module AVM
module ImageQuality
- %w{Good Moderate Poor}.each do |type|
- klass = Class.new do
- def to_s
- self.class.to_s.split('::').last
- end
- end
+ TERMS = %w{Good Moderate Poor}
- AVM::ImageQuality.const_set(type.to_sym, klass)
- end
+ include AVM::ControlledVocabulary
end
end
diff --git a/lib/avm/image_type.rb b/lib/avm/image_type.rb
index 5c6725c..fb379ec 100644
--- a/lib/avm/image_type.rb
+++ b/lib/avm/image_type.rb
@@ -1,14 +1,10 @@
+require 'avm/controlled_vocabulary'
+
module AVM
module ImageType
- %w{Observation Artwork Photographic Planetary Simulation Chart Collage}.each do |type|
- klass = Class.new do
- def to_s
- self.class.to_s.split('::').last
- end
- end
+ TERMS = %w{Observation Artwork Photographic Planetary Simulation Chart Collage}
- AVM::ImageType.const_set(type.to_sym, klass)
- end
+ include ControlledVocabulary
end
end
diff --git a/lib/avm/spatial_quality.rb b/lib/avm/spatial_quality.rb
new file mode 100644
index 0000000..7c016d2
--- /dev/null
+++ b/lib/avm/spatial_quality.rb
@@ -0,0 +1,10 @@
+require 'avm/controlled_vocabulary'
+
+module AVM
+ module SpatialQuality
+ TERMS = %w{Full Position}
+
+ include AVM::ControlledVocabulary
+ end
+end
+
diff --git a/spec/avm/image_spec.rb b/spec/avm/image_spec.rb
index 45ad06a..26dfd73 100644
--- a/spec/avm/image_spec.rb
+++ b/spec/avm/image_spec.rb
@@ -21,6 +21,21 @@ describe AVM::Image do
let(:redshift) { 'Redshift' }
let(:light_years) { 'Light years' }
+ let(:coordinate_frame) { 'ICRS' }
+ let(:equinox) { '100' }
+ let(:reference_value) { [ 100, 50 ] }
+ let(:reference_dimension) { [ 200, 150 ] }
+ let(:reference_pixel) { [ 25, 15 ] }
+ let(:spatial_scale) { [ 40, 35 ] }
+ let(:spatial_rotation) { 10 }
+ let(:coordinate_system_projection) { 'TAN' }
+ let(:spatial_quality) { 'Full' }
+ let(:spatial_notes) { 'Spatial Notes' }
+ let(:fits_header) { 'FITS header' }
+ let(:spatial_cd_matrix) { [ 1, 2, 3, 4 ] }
+
+ it "should have spatial information"
+
def self.with_all_options
let(:options) { {
:title => title,
@@ -35,7 +50,19 @@ describe AVM::Image do
:type => type,
:quality => image_quality,
:redshift => redshift,
- :light_years => light_years
+ :light_years => light_years,
+ :coordinate_frame => coordinate_frame,
+ :equinox => equinox,
+ :reference_value => reference_value,
+ :reference_dimension => reference_dimension,
+ :reference_pixel => reference_pixel,
+ :spatial_scale => spatial_scale,
+ :spatial_rotation => spatial_rotation,
+ :coordinate_system_projection => coordinate_system_projection,
+ :spatial_quality => spatial_quality,
+ :spatial_notes => spatial_notes,
+ :fits_header => fits_header,
+ :spatial_cd_matrix => spatial_cd_matrix,
} }
end
@@ -52,6 +79,19 @@ describe AVM::Image do
its(:id) { should == id }
its(:image_type) { should be_a_kind_of eval("AVM::ImageType::#{type}") }
its(:image_quality) { should be_a_kind_of eval("AVM::ImageQuality::#{image_quality}") }
+
+ its(:coordinate_frame) { should be_a_kind_of eval("AVM::CoordinateFrame::#{coordinate_frame}") }
+ its(:equinox) { should == equinox }
+ its(:reference_value) { should == reference_value }
+ its(:reference_dimension) { should == reference_dimension }
+ its(:reference_pixel) { should == reference_pixel }
+ its(:spatial_scale) { should == spatial_scale }
+ its(:spatial_rotation) { should == spatial_rotation }
+ its(:coordinate_system_projection) { should be_a_kind_of eval("AVM::CoordinateSystemProjection::#{coordinate_system_projection}") }
+ its(:spatial_quality) { should be_a_kind_of eval("AVM::SpatialQuality::#{spatial_quality}") }
+ its(:spatial_notes) { should == spatial_notes }
+ its(:fits_header) { should == fits_header }
+ its(:spatial_cd_matrix) { should == spatial_cd_matrix }
end
describe '#initialize' do
@@ -72,21 +112,18 @@ describe AVM::Image do
context "nothing in it" do
let(:file_path) { 'spec/sample_files/image/nothing.xmp' }
- its(:title) { should be_nil }
- its(:headline) { should be_nil }
- its(:description) { should be_nil }
- its(:distance_notes) { should be_nil }
- its(:spectral_notes) { should be_nil }
- its(:reference_url) { should be_nil }
- its(:credit) { should be_nil }
- its(:date) { should be_nil }
- its(:id) { should be_nil }
- its(:image_type) { should be_nil }
- its(:image_quality) { should be_nil }
- its(:redshift) { should be_nil }
- its(:light_years) { should be_nil }
+ [ :title, :headline, :description, :distance_notes,
+ :spectral_notes, :reference_url, :credit, :date,
+ :id, :image_type, :image_quality, :redshift,
+ :light_years, :coordinate_frame, :equinox, :reference_value,
+ :reference_dimension, :reference_pixel, :spatial_scale,
+ :spatial_rotation, :coordinate_system_projection, :spatial_quality, :spatial_notes,
+ :fits_header, :spatial_cd_matrix
+ ].each do |field|
+ its(field) { should be_nil }
+ end
end
-
+
context "image in it" do
context "distance in light years" do
let(:file_path) { 'spec/sample_files/image/light_years.xmp' }
diff --git a/spec/sample_files/image/both.xmp b/spec/sample_files/image/both.xmp
index cdcddd8..79f615c 100644
--- a/spec/sample_files/image/both.xmp
+++ b/spec/sample_files/image/both.xmp
@@ -39,6 +39,45 @@
Redshift
+ ICRS
+ 100
+
+
+ 100
+ 50
+
+
+
+
+ 200
+ 150
+
+
+
+
+ 25
+ 15
+
+
+
+
+ 40
+ 35
+
+
+ 10
+ TAN
+ Full
+ Spatial Notes
+ FITS header
+
+
+ 1
+ 2
+ 3
+ 4
+
+
diff --git a/spec/sample_files/image/light_years.xmp b/spec/sample_files/image/light_years.xmp
index aa7781d..01c25e0 100644
--- a/spec/sample_files/image/light_years.xmp
+++ b/spec/sample_files/image/light_years.xmp
@@ -12,7 +12,6 @@
Description
-
@@ -34,6 +33,45 @@
Observation
Good
Light years
+ ICRS
+ 100
+
+
+ 100
+ 50
+
+
+
+
+ 200
+ 150
+
+
+
+
+ 25
+ 15
+
+
+
+
+ 40
+ 35
+
+
+ 10
+ TAN
+ Full
+ Spatial Notes
+ FITS header
+
+
+ 1
+ 2
+ 3
+ 4
+
+
diff --git a/spec/sample_files/image/redshift.xmp b/spec/sample_files/image/redshift.xmp
index a48395c..0023b24 100644
--- a/spec/sample_files/image/redshift.xmp
+++ b/spec/sample_files/image/redshift.xmp
@@ -39,6 +39,45 @@
Redshift
+ ICRS
+ 100
+
+
+ 100
+ 50
+
+
+
+
+ 200
+ 150
+
+
+
+
+ 25
+ 15
+
+
+
+
+ 40
+ 35
+
+
+ 10
+ TAN
+ Full
+ Spatial Notes
+ FITS header
+
+
+ 1
+ 2
+ 3
+ 4
+
+