adiwg-mdtranslator 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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