adiwg-mdtranslator 2.2.0 → 2.3.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.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/lib/adiwg/mdtranslator/internal/internal_metadata_obj.rb +23 -23
  3. data/lib/adiwg/mdtranslator/readers/fgdc/fgdc_reader.rb +1 -0
  4. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_attribute.rb +110 -0
  5. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_digitalForm.rb +69 -0
  6. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_distribution.rb +82 -1
  7. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_entity.rb +72 -0
  8. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_entityAttribute.rb +32 -1
  9. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_entityOverview.rb +45 -0
  10. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_enumerated.rb +50 -0
  11. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_fgdc.rb +29 -13
  12. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_identification.rb +1 -1
  13. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_metadataInfo.rb +125 -1
  14. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_offlineOption.rb +98 -0
  15. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_onlineOption.rb +81 -0
  16. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_orderProcess.rb +79 -0
  17. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_pointVector.rb +102 -0
  18. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_range.rb +50 -0
  19. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_raster.rb +84 -0
  20. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_spatialOrganization.rb +48 -2
  21. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_timePeriod.rb +20 -1
  22. data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_transferInfo.rb +87 -0
  23. data/lib/adiwg/mdtranslator/version.rb +2 -1
  24. metadata +15 -3
@@ -0,0 +1,79 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc distribution order process
3
+
4
+ # History:
5
+ # Stan Smith 2017-09-08 original script
6
+
7
+ require 'nokogiri'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+ require_relative 'module_digitalForm'
10
+
11
+ module ADIWG
12
+ module Mdtranslator
13
+ module Readers
14
+ module Fgdc
15
+
16
+ module OrderProcess
17
+
18
+ def self.unpack(xOrder, hDistributor, hResponseObj)
19
+
20
+ # instance classes needed in script
21
+ intMetadataClass = InternalMetadata.new
22
+ hOrder = intMetadataClass.newOrderProcess
23
+
24
+ # distribution 6.4.1 (nondig) - non-digital form
25
+ # -> place as offline option
26
+ # -> distribution.distributor.transferOption.offlineOption.note
27
+ nonDigital = xOrder.xpath('./nondig').text
28
+ unless nonDigital.empty?
29
+ hTransfer = intMetadataClass.newTransferOption
30
+ hOffline = intMetadataClass.newMedium
31
+ hOffline[:note] = nonDigital
32
+ hTransfer[:offlineOptions] << hOffline
33
+ hDistributor[:transferOptions] << hTransfer
34
+ end
35
+
36
+ # distribution 6.4.2 (digform) - digital form []
37
+ axDigital = xOrder.xpath('./digform')
38
+ unless axDigital.empty?
39
+ axDigital.each do |xDigiForm|
40
+ hReturn = DigitalForm.unpack(xDigiForm, hResponseObj)
41
+ unless hReturn.nil?
42
+ hDistributor[:transferOptions] << hReturn
43
+ end
44
+ end
45
+ end
46
+
47
+ # distribution 6.4.3 (fees) - fees
48
+ # -> distribution.distributor.orderProcess.fees
49
+ fees = xOrder.xpath('./fees').text
50
+ unless fees.empty?
51
+ hOrder[:fees] = fees
52
+ end
53
+
54
+ # distribution 6.4.4 (ordering) - ordering information
55
+ # -> distribution.distributor.orderProcess.orderingInstructions
56
+ instructions = xOrder.xpath('./ordering').text
57
+ unless instructions.empty?
58
+ hOrder[:orderingInstructions] = instructions
59
+ end
60
+
61
+ # distribution 6.4.5 (turnarnd) - turnaround time
62
+ # -> distribution.distributor.orderProcess.turnaround
63
+ turnaround = xOrder.xpath('./turnarnd').text
64
+ unless turnaround.empty?
65
+ hOrder[:turnaround] = turnaround
66
+ end
67
+
68
+ hDistributor[:orderProcess] << hOrder
69
+
70
+ return hDistributor
71
+
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,102 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc point and vector data organization
3
+
4
+ # History:
5
+ # Stan Smith 2017-09-01 original script
6
+
7
+ require 'nokogiri'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+
10
+ module ADIWG
11
+ module Mdtranslator
12
+ module Readers
13
+ module Fgdc
14
+
15
+ module PointVector
16
+
17
+ def self.unpack(xPtVec, hResourceInfo, hResponseObj)
18
+
19
+ # instance classes needed in script
20
+ intMetadataClass = InternalMetadata.new
21
+
22
+ # point and vector object 3.3.1 (sdtsterm) - SDTS term []
23
+ axSDTSterm = xPtVec.xpath('./sdtsterm')
24
+ unless axSDTSterm.empty?
25
+ hVectorInfo = intMetadataClass.newVectorInfo
26
+
27
+ axSDTSterm.each do |xTerm|
28
+ hVectorObj = intMetadataClass.newVectorObject
29
+
30
+ # SDTS term 3.3.1.1 (sdtstype) - point and vector object type
31
+ # -> spatialRepresentation.vectorInfo.vectorObject.objectType
32
+ sdtsType = xTerm.xpath('./sdtstype').text
33
+ unless sdtsType.empty?
34
+ hVectorObj[:objectType] = sdtsType
35
+ end
36
+
37
+ # SDTS term 3.3.1.2 (ptvctcnt) - point and vector object count
38
+ # -> spatialRepresentation.vectorInfo.vectorObject.objectCount
39
+ ptvCount = xTerm.xpath('./ptvctcnt').text
40
+ unless ptvCount.empty?
41
+ hVectorObj[:objectCount] = ptvCount.to_i
42
+ end
43
+
44
+ hVectorInfo[:vectorObject] << hVectorObj
45
+ end
46
+
47
+ hSpatialRepresentation = intMetadataClass.newSpatialRepresentation
48
+ hSpatialRepresentation[:vectorRepresentation] = hVectorInfo
49
+ hResourceInfo[:spatialRepresentations] << hSpatialRepresentation
50
+ end
51
+
52
+ # point and vector object 3.3.2 (vpfterm) - VPF terms description
53
+ xVPFterm = xPtVec.xpath('./vpfterm')
54
+ unless xVPFterm.empty?
55
+ hVectorInfo = intMetadataClass.newVectorInfo
56
+
57
+ # VPF term 3.3.2.1 (vpflevel) - VPF topology level
58
+ # -> spatialRepresentation.vectorInfo.topologyLevel
59
+ level = xVPFterm.xpath('vpflevel').text
60
+ unless level.empty?
61
+ hVectorInfo[:topologyLevel] = level.to_i
62
+ end
63
+
64
+ # VPF term 3.3.2.2 (vpfinfo) - VPF point and vector object information []
65
+ axVPFInfo = xVPFterm.xpath('./vpfinfo')
66
+ unless axVPFInfo.empty?
67
+ axVPFInfo.each do |xInfo|
68
+ hVectorObj = intMetadataClass.newVectorObject
69
+
70
+ # VPF point and object 3.3.2.2.1 (vpftype) - VPF point and vector object type
71
+ # -> spatialRepresentation.vectorInfo.vectorObject.objectType
72
+ vpfType = xInfo.xpath('./vpftype').text
73
+ unless vpfType.empty?
74
+ hVectorObj[:objectType] = vpfType
75
+ end
76
+
77
+ # VPF point and object 3.3.2.2.2 (ptvctcnt) - VPF point and vector object count
78
+ # -> spatialRepresentation.vectorInfo.vectorObject.objectCount
79
+ vpfCount = xInfo.xpath('./ptvctcnt').text
80
+ unless vpfCount.empty?
81
+ hVectorObj[:objectCount] = vpfCount.to_i
82
+ end
83
+
84
+ hVectorInfo[:vectorObject] << hVectorObj
85
+ end
86
+
87
+ hSpatialRepresentation = intMetadataClass.newSpatialRepresentation
88
+ hSpatialRepresentation[:vectorRepresentation] = hVectorInfo
89
+ hResourceInfo[:spatialRepresentations] << hSpatialRepresentation
90
+ end
91
+
92
+ end
93
+
94
+ return hResourceInfo
95
+
96
+ end
97
+ end
98
+
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,50 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc entity range domain
3
+
4
+ # History:
5
+ # Stan Smith 2017-09-06 original script
6
+
7
+ require 'nokogiri'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+
10
+ module ADIWG
11
+ module Mdtranslator
12
+ module Readers
13
+ module Fgdc
14
+
15
+ module Range
16
+
17
+ def self.unpack(xRange, hAttribute, hResponseObj)
18
+
19
+ # entity attribute 5.1.2.4.2.1 (rdommin) - range minimum
20
+ # -> dataDictionary.entities.attributes.minValue
21
+ min = xRange.xpath('./rdommin').text
22
+ unless min.empty?
23
+ hAttribute[:minValue] = min
24
+ end
25
+
26
+ # entity attribute 5.1.2.4.2.2 (rdommax) - range maximum
27
+ # -> dataDictionary.entities.attributes.maxValue
28
+ max = xRange.xpath('./rdommax').text
29
+ unless max.empty?
30
+ hAttribute[:maxValue] = max
31
+ end
32
+
33
+ # entity attribute 5.1.2.4.2.3 (attrunit) - units of measure
34
+ # -> dataDictionary.entities.attributes.unitOfMeasure
35
+ units = xRange.xpath('./attrunit').text
36
+ unless units.empty?
37
+ hAttribute[:unitOfMeasure] = units
38
+ end
39
+
40
+ # entity attribute 5.1.2.4.2.4 (attrmres) - measurement resolution
41
+ # -> not mapped
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,84 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc raster data organization
3
+
4
+ # History:
5
+ # Stan Smith 2017-09-01 original script
6
+
7
+ require 'nokogiri'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+
10
+ module ADIWG
11
+ module Mdtranslator
12
+ module Readers
13
+ module Fgdc
14
+
15
+ module Raster
16
+
17
+ def self.unpack(xRaster, hResourceInfo, hResponseObj)
18
+
19
+ # instance classes needed in script
20
+ intMetadataClass = InternalMetadata.new
21
+ hSpatialRepresentation = intMetadataClass.newSpatialRepresentation
22
+ hGridInfo = intMetadataClass.newGridInfo
23
+
24
+ # raster object 3.4.1 (rasttype) - raster object type
25
+ # -> spatialRepresentation.gridInfo.numberOfDimensions per NOAA
26
+ # -> FGDC and ISO definitions do not match on this element
27
+ # -> however elements do match on spatialRepresentation.gridInfo.cellGeometry
28
+ cellGeometry = xRaster.xpath('./rasttype').text
29
+ unless cellGeometry.empty?
30
+ hGridInfo[:cellGeometry] = cellGeometry.downcase
31
+ end
32
+
33
+ # -> make number of dimensions from total occurrence of 3.4.2-4
34
+ hGridInfo[:numberOfDimensions] = 0
35
+
36
+ # raster object 3.4.2 (rowcount) - row count
37
+ # -> spatialRepresentation.gridInfo.dimension.dimensionSize
38
+ # -> spatialRepresentation.gridInfo.dimension.dimensionType = row
39
+ rows = xRaster.xpath('./rowcount').text
40
+ unless rows.empty?
41
+ hDimension = intMetadataClass.newDimension
42
+ hDimension[:dimensionType] = 'row'
43
+ hDimension[:dimensionSize] = rows.to_i
44
+ hGridInfo[:dimension] << hDimension
45
+ hGridInfo[:numberOfDimensions] += 1
46
+ end
47
+
48
+ # raster object 3.4.3 (colcount) - column count
49
+ # -> spatialRepresentation.gridInfo.dimension.dimensionSize
50
+ # -> spatialRepresentation.gridInfo.dimension.dimensionType = column
51
+ columns = xRaster.xpath('./colcount').text
52
+ unless columns.empty?
53
+ hDimension = intMetadataClass.newDimension
54
+ hDimension[:dimensionType] = 'column'
55
+ hDimension[:dimensionSize] = columns.to_i
56
+ hGridInfo[:dimension] << hDimension
57
+ hGridInfo[:numberOfDimensions] += 1
58
+ end
59
+
60
+ # raster object 3.4.4 (vrtcount) - vertical count
61
+ # -> spatialRepresentation.gridInfo.dimension.dimensionSize
62
+ # -> spatialRepresentation.gridInfo.dimension.dimensionType = vertical
63
+ verts = xRaster.xpath('./vrtcount').text
64
+ unless verts.empty?
65
+ hDimension = intMetadataClass.newDimension
66
+ hDimension[:dimensionType] = 'vertical'
67
+ hDimension[:dimensionSize] = verts.to_i
68
+ hGridInfo[:dimension] << hDimension
69
+ hGridInfo[:numberOfDimensions] += 1
70
+ end
71
+
72
+ hSpatialRepresentation[:gridRepresentation] = hGridInfo
73
+ hResourceInfo[:spatialRepresentations] << hSpatialRepresentation
74
+
75
+ return hResourceInfo
76
+
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+ end
@@ -6,6 +6,8 @@
6
6
 
7
7
  require 'nokogiri'
8
8
  require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+ require_relative 'module_pointVector'
10
+ require_relative 'module_raster'
9
11
 
10
12
  module ADIWG
11
13
  module Mdtranslator
@@ -14,12 +16,56 @@ module ADIWG
14
16
 
15
17
  module SpatialOrganization
16
18
 
17
- def self.unpack(xSpatialOrg, hResponseObj)
19
+ def self.unpack(xSpatialOrg, hResourceInfo, hResponseObj)
18
20
 
21
+ # instance classes needed in script
22
+ intMetadataClass = InternalMetadata.new
19
23
 
24
+ # spatial organization 3.1 (indspref) - indirect spatial reference
25
+ # -> resourceInfo.spatialReferenceSystems.spatialReferenceSystem.systemIdentifier.identifier per NOAA
26
+ # -> however definitions are not close
27
+ indirect = xSpatialOrg.xpath('./indspref').text
28
+ unless indirect.empty?
29
+ hSystem = intMetadataClass.newSpatialReferenceSystem
30
+ hIdentifier = intMetadataClass.newIdentifier
31
+ hIdentifier[:identifier] = indirect
32
+ hSystem[:systemIdentifier] = hIdentifier
33
+ hResourceInfo[:spatialReferenceSystems] << hSystem
34
+ end
20
35
 
21
- end
36
+ # spatial organization 3.2 (direct) - direct spatial reference method
37
+ # -> resourceInfo.spatialRepresentationTypes, translate FGDC to ISO as:
38
+ # -> point = vector do 3.3
39
+ # -> vector = vector do 3.3
40
+ # -> raster = grid do 3.4
41
+ direct = xSpatialOrg.xpath('./direct').text
42
+ unless direct.empty?
43
+ type = 'vector' if direct == 'Point'
44
+ type = 'vector' if direct == 'Vector'
45
+ type = 'grid' if direct == 'Raster'
46
+ hResourceInfo[:spatialRepresentationTypes] << type
47
+
48
+ # spatial organization 3.3 (ptvctinfo) - point and vector object
49
+ if type == 'vector'
50
+ xPtVec = xSpatialOrg.xpath('./ptvctinf')
51
+ unless xPtVec.empty?
52
+ PointVector.unpack(xPtVec, hResourceInfo, hResponseObj)
53
+ end
54
+ end
55
+
56
+ # spatial organization 3.4 (rastinfo) - raster object
57
+ if type == 'grid'
58
+ xRaster = xSpatialOrg.xpath('./rastinfo')
59
+ unless xRaster.empty?
60
+ Raster.unpack(xRaster, hResourceInfo, hResponseObj)
61
+ end
62
+ end
22
63
 
64
+ end
65
+
66
+ return hResourceInfo
67
+
68
+ end
23
69
  end
24
70
 
25
71
  end
@@ -54,7 +54,26 @@ module ADIWG
54
54
  end
55
55
 
56
56
  # time period 9.2 (mdattim) - multiple date times
57
- # placed in temporal extent
57
+ # take first date
58
+ xMulti = xTimeInfo.xpath('./mdattim')
59
+ unless xMulti.empty?
60
+ axSingle = xMulti.xpath('./sngdate')
61
+
62
+ # use first occurrence of the multiple date times
63
+ unless axSingle.empty?
64
+ xSingle = axSingle[0]
65
+ date = xSingle.xpath('./caldate').text
66
+ time = xSingle.xpath('./time').text
67
+ hDateTime = DateTime.unpack(date, time, hResponseObj)
68
+ unless hDateTime.nil?
69
+ hTimePeriod[:startDateTime] = hDateTime
70
+ end
71
+ hTimePeriod[:description] = current
72
+
73
+ return hTimePeriod
74
+
75
+ end
76
+ end
58
77
 
59
78
  # time period 9.3 (rngdates) - range of dates
60
79
  xRange = xTimeInfo.xpath('./rngdates')
@@ -0,0 +1,87 @@
1
+ # Reader - fgdc to internal data structure
2
+ # unpack fgdc distribution digital transfer information
3
+
4
+ # History:
5
+ # Stan Smith 2017-09-09 original script
6
+
7
+ require 'nokogiri'
8
+ require 'adiwg/mdtranslator/internal/internal_metadata_obj'
9
+ require_relative 'module_date'
10
+
11
+ module ADIWG
12
+ module Mdtranslator
13
+ module Readers
14
+ module Fgdc
15
+
16
+ module TransferInfo
17
+
18
+ def self.unpack(xTranInfo, hTransfer, hResponseObj)
19
+
20
+ # instance classes needed in script
21
+ intMetadataClass = InternalMetadata.new
22
+ hFormat = intMetadataClass.newResourceFormat
23
+ hSpecification = intMetadataClass.newCitation
24
+ hFormat[:formatSpecification] = hSpecification
25
+ hTransfer[:distributionFormats] << hFormat
26
+
27
+ # distribution 6.4.2.1.1 (formname) - format name
28
+ # -> distribution.distributor.transferOption.distributionFormat.formatSpecification.title
29
+ title = xTranInfo.xpath('./formname').text
30
+ unless title.empty?
31
+ hSpecification[:title] = title
32
+ end
33
+
34
+ # distribution 6.4.2.1.2 (formvern) - format version number
35
+ # -> distribution.distributor.transferOption.distributionFormat.formatSpecification.edition
36
+ version = xTranInfo.xpath('./formvern').text
37
+ unless version.empty?
38
+ hSpecification[:edition] = version
39
+ end
40
+
41
+ # distribution 6.4.2.1.3 (formverd) - format version date
42
+ # -> distribution.distributor.transferOption.distributionFormat.formatSpecification.date(version)
43
+ date = xTranInfo.xpath('./formverd').text
44
+ unless date.empty?
45
+ hDate = Date.unpack(date, '', 'revision', hResponseObj)
46
+ unless hDate.nil?
47
+ hSpecification[:dates] << hDate
48
+ end
49
+ end
50
+
51
+ # distribution 6.4.2.1.4 (formspec) - format specification
52
+ # -> distribution.distributor.transferOption.distributionFormat.formatSpecification.otherCitationDetails
53
+ specification = xTranInfo.xpath('./formspec').text
54
+ unless specification.empty?
55
+ hSpecification[:otherDetails] << specification
56
+ end
57
+
58
+ # distribution 6.4.2.1.5 (formcont) - format information content
59
+ # -> distribution.distributor.transferOption.distributionFormat.formatSpecification.otherCitationDetails
60
+ specification = xTranInfo.xpath('./formcont').text
61
+ unless specification.empty?
62
+ hSpecification[:otherDetails] << specification
63
+ end
64
+
65
+ # distribution 6.4.2.1.6 (filedec) - file decompression technique
66
+ # -> distribution.distributor.transferOption.distributionFormat.compressionMethod
67
+ compress = xTranInfo.xpath('./filedec').text
68
+ unless compress.empty?
69
+ hFormat[:compressionMethod] = compress
70
+ end
71
+
72
+ # distribution 6.4.2.1.7 (transize) - file transfer size in MB
73
+ # -> distribution.distributor.transferOption.transferSize
74
+ size = xTranInfo.xpath('./transize').text
75
+ unless size.empty?
76
+ hTransfer[:transferSize] = size.to_i
77
+ end
78
+
79
+ return hTransfer
80
+
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+ end