adiwg-mdtranslator 2.1.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -0
- data/adiwg-mdtranslator.gemspec +1 -0
- data/lib/adiwg/mdtranslator/internal/module_coordinates.rb +13 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/fgdc_reader.rb +49 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_citation.rb +144 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_date.rb +57 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_dateTime.rb +108 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_distribution.rb +28 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_entityAttribute.rb +28 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_fgdc.rb +193 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_identification.rb +136 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_metadataInfo.rb +28 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_onlineResource.rb +35 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_publication.rb +63 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_quality.rb +28 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_responsibility.rb +46 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_series.rb +44 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_spatialDomain.rb +184 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_spatialOrganization.rb +28 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_spatialReference.rb +28 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_timeInstant.rb +40 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/modules/module_timePeriod.rb +88 -0
- data/lib/adiwg/mdtranslator/readers/fgdc/readme.md +18 -0
- data/lib/adiwg/mdtranslator/readers/{fgcd → fgdc}/version.rb +0 -0
- data/lib/adiwg/mdtranslator/readers/mdJson/readme.md +1 -1
- data/lib/adiwg/mdtranslator/readers/mdJson/version.rb +2 -1
- data/lib/adiwg/mdtranslator/readers/sbJson/modules/module_browseCategory.rb +5 -5
- data/lib/adiwg/mdtranslator/readers/sbJson/modules/module_relatedItem.rb +4 -10
- data/lib/adiwg/mdtranslator/readers/sbJson/modules/module_sbJson.rb +1 -1
- data/lib/adiwg/mdtranslator/readers/sbJson/readme.md +1 -1
- data/lib/adiwg/mdtranslator/readers/sbJson/sbJson_reader.rb +2 -2
- data/lib/adiwg/mdtranslator/readers/sbJson/version.rb +1 -1
- data/lib/adiwg/mdtranslator/version.rb +1 -1
- data/lib/adiwg/mdtranslator/writers/mdJson/sections/mdJson_resourceType.rb +1 -0
- metadata +37 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2be0aaa21383741efd06ac414b0ba47453777e6
|
4
|
+
data.tar.gz: 5eb25c34b45babdff52a7fadaa0e32668d2b0c9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b085419641422ad940aec5f9bbc2b014585f76a1063750012bb2274711f934cc126e32a62d1e2783855d0f4ee6f321ab21632ca07f65d7e3d69f896b54bd1ff5
|
7
|
+
data.tar.gz: 7e5912f670bacbdca633ec763742be8f703a95c0b5fd107407eaf3f7a875cb6e23995001557b37844b74db21c07f3db106f4e77212ae8b5a0b32870e8e1c16a7
|
data/Rakefile
CHANGED
data/adiwg-mdtranslator.gemspec
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# repack coordinates
|
2
2
|
|
3
3
|
# History:
|
4
|
+
# Stan Smith 2017-08-23 added is_polygon_clockwise method
|
4
5
|
# Stan Smith 2017-05-24 added checkGeometry method to move objects to real world
|
5
6
|
# Stan Smith 2016-11-10 added computedBbox computation
|
6
7
|
# Stan Smith 2015-07-16 moved module_coordinates from mdJson reader to internal
|
@@ -219,4 +220,16 @@ module AdiwgCoordinates
|
|
219
220
|
aNorthings << aPoint[1]
|
220
221
|
end
|
221
222
|
|
223
|
+
def self.is_polygon_clockwise(aCoords)
|
224
|
+
area = 0.0
|
225
|
+
i = 0
|
226
|
+
n = aCoords.length - 1
|
227
|
+
until i == n
|
228
|
+
area += (aCoords[i][0] * aCoords[i+1][1]) - (aCoords[i][1] * aCoords[i+1][0])
|
229
|
+
i += 1
|
230
|
+
end
|
231
|
+
area += (aCoords[n][0] * aCoords[0][1]) - (aCoords[n][1] * aCoords[0][0])
|
232
|
+
return area >= 0 ? false : true
|
233
|
+
end
|
234
|
+
|
222
235
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# fgdc reader
|
2
|
+
|
3
|
+
# History:
|
4
|
+
# Stan Smith 2017-08-10 original script
|
5
|
+
|
6
|
+
require 'nokogiri'
|
7
|
+
require_relative 'modules/module_fgdc'
|
8
|
+
|
9
|
+
module ADIWG
|
10
|
+
module Mdtranslator
|
11
|
+
module Readers
|
12
|
+
module Fgdc
|
13
|
+
|
14
|
+
def self.readFile(file, hResponseObj)
|
15
|
+
|
16
|
+
# receive XML file
|
17
|
+
if file.nil? || file == ''
|
18
|
+
hResponseObj[:readerStructureMessages] << 'XML file is missing'
|
19
|
+
hResponseObj[:readerStructurePass] = false
|
20
|
+
return {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# file must be well formed XML
|
24
|
+
begin
|
25
|
+
xDoc = Nokogiri::XML(file) { |form| form.strict }
|
26
|
+
rescue Nokogiri::XML::SyntaxError => err
|
27
|
+
hResponseObj[:readerStructureMessages] << 'XML file is not well formed'
|
28
|
+
hResponseObj[:readerStructureMessages] << err
|
29
|
+
hResponseObj[:readerStructurePass] = false
|
30
|
+
return {}
|
31
|
+
end
|
32
|
+
|
33
|
+
# file must contain an fgdc <metadata> tag
|
34
|
+
xMetadata = xDoc.xpath('/metadata')
|
35
|
+
if xMetadata.empty?
|
36
|
+
hResponseObj[:readerValidationMessages] << 'FGDC file did not contain a <metadata> tag'
|
37
|
+
hResponseObj[:readerValidationPass] = false
|
38
|
+
return {}
|
39
|
+
end
|
40
|
+
|
41
|
+
# load fgdc file into internal object
|
42
|
+
return Fgdc.unpack(xDoc, hResponseObj)
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# Reader - fgdc to internal data structure
|
2
|
+
# unpack fgdc citation
|
3
|
+
|
4
|
+
# History:
|
5
|
+
# Stan Smith 2017-08-15 original script
|
6
|
+
|
7
|
+
require 'nokogiri'
|
8
|
+
require 'uuidtools'
|
9
|
+
require 'adiwg/mdtranslator/internal/internal_metadata_obj'
|
10
|
+
require_relative 'module_fgdc'
|
11
|
+
require_relative 'module_date'
|
12
|
+
require_relative 'module_series'
|
13
|
+
require_relative 'module_publication'
|
14
|
+
require_relative 'module_onlineResource'
|
15
|
+
require_relative 'module_citation'
|
16
|
+
require_relative 'module_responsibility'
|
17
|
+
|
18
|
+
module ADIWG
|
19
|
+
module Mdtranslator
|
20
|
+
module Readers
|
21
|
+
module Fgdc
|
22
|
+
|
23
|
+
module Citation
|
24
|
+
|
25
|
+
def self.unpack(xCitation, hResponseObj)
|
26
|
+
|
27
|
+
xCiteInfo = xCitation.xpath('./citeinfo')
|
28
|
+
|
29
|
+
# instance classes needed in script
|
30
|
+
intMetadataClass = InternalMetadata.new
|
31
|
+
hCitation = intMetadataClass.newCitation
|
32
|
+
|
33
|
+
# citation 8.1 (origin) - originator [] (required)
|
34
|
+
aContacts = []
|
35
|
+
axOrigins = xCiteInfo.xpath('./origin')
|
36
|
+
axOrigins.each do |xOrigin|
|
37
|
+
name = xOrigin.text
|
38
|
+
unless name.empty?
|
39
|
+
contactId = Fgdc.find_contact_by_name(name)
|
40
|
+
if contactId.nil?
|
41
|
+
# add a new contact for this originator
|
42
|
+
contactId = Fgdc.add_contact(name, false)
|
43
|
+
aContacts << contactId
|
44
|
+
else
|
45
|
+
aContacts << contactId
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
unless aContacts.empty?
|
50
|
+
hResponsibility = Responsibility.unpack(aContacts, 'originator', hResponseObj)
|
51
|
+
unless hResponsibility.nil?
|
52
|
+
hCitation[:responsibleParties] << hResponsibility
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# citation 8.2/8.3 (pubdate/pubtime) - publication date/time {date} (required) {time} (optional)
|
57
|
+
pubDate = xCiteInfo.xpath('./pubdate').text
|
58
|
+
pubTime = xCiteInfo.xpath('./pubtime').text
|
59
|
+
unless pubDate.empty?
|
60
|
+
hDate = Date.unpack(pubDate, pubTime, 'publication', hResponseObj)
|
61
|
+
unless hDate.nil?
|
62
|
+
hCitation[:dates] << hDate
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# citation 8.4 (title) - citation title (required)
|
67
|
+
title = xCiteInfo.xpath('./title').text
|
68
|
+
unless title.empty?
|
69
|
+
hCitation[:title] = title
|
70
|
+
end
|
71
|
+
|
72
|
+
# citation 8.5 (edition) - edition
|
73
|
+
edition = xCiteInfo.xpath('./edition').text
|
74
|
+
unless edition.empty?
|
75
|
+
hCitation[:edition] = edition
|
76
|
+
end
|
77
|
+
|
78
|
+
# citation 8.6 (geoform) - edition
|
79
|
+
presentationForm = xCiteInfo.xpath('./geoform').text
|
80
|
+
unless presentationForm.empty?
|
81
|
+
hCitation[:presentationForms] << presentationForm
|
82
|
+
end
|
83
|
+
|
84
|
+
# citation 8.7 (serinfo) - series information
|
85
|
+
xSeries = xCiteInfo.xpath('./serinfo')
|
86
|
+
unless xSeries.empty?
|
87
|
+
hSeries = Series.unpack(xSeries, hResponseObj)
|
88
|
+
unless hSeries.nil?
|
89
|
+
hCitation[:series] = hSeries
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# citation 8.8 (pubinfo) - publication information
|
94
|
+
xPublication = xCiteInfo.xpath('./pubinfo')
|
95
|
+
unless xPublication.empty?
|
96
|
+
hResponsibility = Publication.unpack(xPublication, hResponseObj)
|
97
|
+
unless hResponsibility.nil?
|
98
|
+
hCitation[:responsibleParties] << hResponsibility
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# citation 8.9 (othercit) - other citation details
|
103
|
+
other = xCiteInfo.xpath('./othercit').text
|
104
|
+
unless other.empty?
|
105
|
+
hCitation[:otherDetails] << other
|
106
|
+
end
|
107
|
+
|
108
|
+
# citation 8.10 (onlink) - online linkage []
|
109
|
+
axOnLink = xCiteInfo.xpath('./onlink')
|
110
|
+
unless axOnLink.empty?
|
111
|
+
description = 'Link to the resource described in this citation'
|
112
|
+
axOnLink.each do |xLink|
|
113
|
+
onLink = xLink.text
|
114
|
+
unless onLink.empty?
|
115
|
+
hURI = OnlineResource.unpack(onLink, description, hResponseObj)
|
116
|
+
unless hURI.nil?
|
117
|
+
hCitation[:onlineResources] << hURI
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# citation 8.11 (lworkcit) - larger work citation
|
124
|
+
xLWCitation = xCiteInfo.xpath('./lworkcit')
|
125
|
+
unless xLWCitation.empty?
|
126
|
+
hLWCitation = Citation.unpack(xLWCitation, hResponseObj)
|
127
|
+
unless hLWCitation.nil?
|
128
|
+
hAssResource = intMetadataClass.newAssociatedResource
|
129
|
+
hAssResource[:associationType] = 'largerWorkCitation'
|
130
|
+
hAssResource[:resourceCitation] = hLWCitation
|
131
|
+
Fgdc.add_associated_resource(hAssResource)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
return hCitation
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Reader - fgdc to internal data structure
|
2
|
+
# unpack fgdc metadata date
|
3
|
+
|
4
|
+
# History:
|
5
|
+
# Stan Smith 2017-08-15 original script
|
6
|
+
|
7
|
+
require 'date'
|
8
|
+
require 'adiwg/mdtranslator/internal/internal_metadata_obj'
|
9
|
+
require 'adiwg/mdtranslator/internal/module_dateTimeFun'
|
10
|
+
require_relative 'module_fgdc'
|
11
|
+
require_relative 'module_dateTime'
|
12
|
+
|
13
|
+
module ADIWG
|
14
|
+
module Mdtranslator
|
15
|
+
module Readers
|
16
|
+
module Fgdc
|
17
|
+
|
18
|
+
module Date
|
19
|
+
|
20
|
+
def self.unpack(date, time, type, hResponseObj)
|
21
|
+
|
22
|
+
# instance classes needed in script
|
23
|
+
intMetadataClass = InternalMetadata.new
|
24
|
+
hDate = intMetadataClass.newDate
|
25
|
+
|
26
|
+
if date.nil? || date == ''
|
27
|
+
hResponseObj[:readerExecutionMessages] << 'date string is missing from date conversion'
|
28
|
+
hResponseObj[:readerExecutionPass] = false
|
29
|
+
return nil
|
30
|
+
end
|
31
|
+
|
32
|
+
if type.nil? || type == ''
|
33
|
+
hResponseObj[:readerExecutionMessages] << 'date type is missing from date conversion'
|
34
|
+
hResponseObj[:readerExecutionPass] = false
|
35
|
+
return nil
|
36
|
+
end
|
37
|
+
|
38
|
+
hDateTime = DateTime.unpack(date, time, hResponseObj)
|
39
|
+
|
40
|
+
# build internal date object
|
41
|
+
unless hDateTime.nil?
|
42
|
+
hDate[:date] = hDateTime[:dateTime]
|
43
|
+
hDate[:dateResolution] = hDateTime[:dateResolution]
|
44
|
+
hDate[:dateType] = type
|
45
|
+
return hDate
|
46
|
+
end
|
47
|
+
|
48
|
+
return nil
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# Reader - fgdc to internal data structure
|
2
|
+
# unpack fgdc metadata date
|
3
|
+
|
4
|
+
# History:
|
5
|
+
# Stan Smith 2017-08-15 original script
|
6
|
+
|
7
|
+
require 'date'
|
8
|
+
require 'adiwg/mdtranslator/internal/internal_metadata_obj'
|
9
|
+
require 'adiwg/mdtranslator/internal/module_dateTimeFun'
|
10
|
+
require_relative 'module_fgdc'
|
11
|
+
|
12
|
+
module ADIWG
|
13
|
+
module Mdtranslator
|
14
|
+
module Readers
|
15
|
+
module Fgdc
|
16
|
+
|
17
|
+
module DateTime
|
18
|
+
|
19
|
+
def self.unpack(date, time, hResponseObj)
|
20
|
+
|
21
|
+
# instance classes needed in script
|
22
|
+
intMetadataClass = InternalMetadata.new
|
23
|
+
hDateTime = intMetadataClass.newDateTime
|
24
|
+
|
25
|
+
if date.nil? || date == ''
|
26
|
+
hResponseObj[:readerExecutionMessages] << 'date string is missing from dateTime conversion'
|
27
|
+
hResponseObj[:readerExecutionPass] = false
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# convert date from fgdc to iso format
|
32
|
+
year = date.byteslice(0,4)
|
33
|
+
month = date.byteslice(4,2)
|
34
|
+
day = date.byteslice(6,2)
|
35
|
+
month = '01' if month.nil? || month == ''
|
36
|
+
day = '01' if day.nil? || day == ''
|
37
|
+
dtIn = year + '-' + month + '-' + day
|
38
|
+
|
39
|
+
# add time element to date string
|
40
|
+
if time.empty?
|
41
|
+
dtIn = dtIn + 'T' + '00:00:00'
|
42
|
+
else
|
43
|
+
aScan = time.scan(/:/)
|
44
|
+
if aScan.empty?
|
45
|
+
hour = time.byteslice(0,2)
|
46
|
+
minute = time.byteslice(2,2)
|
47
|
+
second = time.byteslice(4,2)
|
48
|
+
else
|
49
|
+
aTime = time.split(':')
|
50
|
+
hour = aTime[0]
|
51
|
+
minute = aTime[1]
|
52
|
+
second = aTime[2]
|
53
|
+
end
|
54
|
+
minute = '00' if minute.nil? || minute == ''
|
55
|
+
second = '00' if second.nil? || second == ''
|
56
|
+
dtIn = dtIn + 'T' + hour + ':' + minute + ':' + second
|
57
|
+
end
|
58
|
+
|
59
|
+
# determine if date/time is 'universal time' or other
|
60
|
+
timeFlag = Fgdc.get_metadata_time_convention
|
61
|
+
timeFlag = 'local time' if timeFlag.nil? || timeFlag == ''
|
62
|
+
|
63
|
+
# add offset to date/time string
|
64
|
+
if timeFlag == 'universal time'
|
65
|
+
dtIn = dtIn + '+00:00'
|
66
|
+
else
|
67
|
+
timeOffset = Time.now.gmt_offset
|
68
|
+
aOffset = timeOffset.divmod(3600)
|
69
|
+
hOffset = aOffset[0]
|
70
|
+
mOffset = aOffset[1] * 60
|
71
|
+
if hOffset >= 0
|
72
|
+
zone = '+' + '%02d' % hOffset + ':' + '%02d' % mOffset
|
73
|
+
else
|
74
|
+
zone = '%03d' % hOffset + ':' + '%02d' % mOffset
|
75
|
+
end
|
76
|
+
dtIn = dtIn + zone
|
77
|
+
end
|
78
|
+
|
79
|
+
# if dateTimeFromString fails, [0] = nil; [1] = 'ERROR'
|
80
|
+
aDateTimeReturn = AdiwgDateTimeFun.dateTimeFromString(dtIn)
|
81
|
+
if aDateTimeReturn[1] == 'ERROR'
|
82
|
+
hResponseObj[:readerExecutionMessages] << 'Date string is invalid'
|
83
|
+
hResponseObj[:readerExecutionPass] = false
|
84
|
+
return nil
|
85
|
+
end
|
86
|
+
|
87
|
+
# if not 'universal time' change the offset to utc
|
88
|
+
dateTimeReturn = aDateTimeReturn[0]
|
89
|
+
if timeFlag == 'universal time'
|
90
|
+
utc = dateTimeReturn
|
91
|
+
else
|
92
|
+
utc = dateTimeReturn.new_offset(Rational(0,24))
|
93
|
+
end
|
94
|
+
|
95
|
+
# build internal dateTime object
|
96
|
+
hDateTime[:dateTime] = utc
|
97
|
+
hDateTime[:dateResolution] = aDateTimeReturn[1]
|
98
|
+
|
99
|
+
return hDateTime
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Reader - fgdc to internal data structure
|
2
|
+
# unpack fgdc distribution
|
3
|
+
|
4
|
+
# History:
|
5
|
+
# Stan Smith 2017-08-15 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 Distribution
|
16
|
+
|
17
|
+
def self.unpack(xDistribution, hResponseObj)
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Reader - fgdc to internal data structure
|
2
|
+
# unpack fgdc entity and attribute
|
3
|
+
|
4
|
+
# History:
|
5
|
+
# Stan Smith 2017-08-15 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 EntityAttribute
|
16
|
+
|
17
|
+
def self.unpack(xEntity, hResponseObj)
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# Reader - fgdc to internal data structure
|
2
|
+
# unpack fgdc metadata
|
3
|
+
|
4
|
+
# History:
|
5
|
+
# Stan Smith 2017-08-10 original script
|
6
|
+
|
7
|
+
require 'nokogiri'
|
8
|
+
require 'uuidtools'
|
9
|
+
require 'adiwg/mdtranslator/internal/internal_metadata_obj'
|
10
|
+
require_relative 'module_identification'
|
11
|
+
require_relative 'module_quality'
|
12
|
+
require_relative 'module_spatialOrganization'
|
13
|
+
require_relative 'module_spatialReference'
|
14
|
+
require_relative 'module_entityAttribute'
|
15
|
+
require_relative 'module_distribution'
|
16
|
+
require_relative 'module_metadataInfo'
|
17
|
+
|
18
|
+
module ADIWG
|
19
|
+
module Mdtranslator
|
20
|
+
module Readers
|
21
|
+
module Fgdc
|
22
|
+
|
23
|
+
module Fgdc
|
24
|
+
|
25
|
+
def self.unpack(xDoc, hResponseObj)
|
26
|
+
|
27
|
+
# instance classes needed in script
|
28
|
+
intMetadataClass = InternalMetadata.new
|
29
|
+
|
30
|
+
intObj = intMetadataClass.newBase
|
31
|
+
@intObj = intObj
|
32
|
+
@contacts = intObj[:contacts]
|
33
|
+
@xDoc = xDoc
|
34
|
+
|
35
|
+
# build basic mdTranslator internal object
|
36
|
+
hMetadata = intMetadataClass.newMetadata
|
37
|
+
hMetadataInfo = intMetadataClass.newMetadataInfo
|
38
|
+
hResourceInfo = intMetadataClass.newResourceInfo
|
39
|
+
hMetadata[:metadataInfo] = hMetadataInfo
|
40
|
+
hMetadata[:resourceInfo] = hResourceInfo
|
41
|
+
intObj[:metadata] = hMetadata
|
42
|
+
|
43
|
+
xMetadata = xDoc.xpath('./metadata')
|
44
|
+
|
45
|
+
# metadata (idinfo 1) - identification information (required)
|
46
|
+
xIdInfo = xMetadata.xpath('./idinfo')
|
47
|
+
unless xIdInfo.empty?
|
48
|
+
Identification.unpack(xIdInfo, intObj, hResponseObj)
|
49
|
+
end
|
50
|
+
if xIdInfo.empty?
|
51
|
+
hResponseObj[:readerExecutionMessages] << 'FGDC is missing identification information section (idinfo)'
|
52
|
+
end
|
53
|
+
|
54
|
+
# metadata (dataqual 2) - data quality
|
55
|
+
xDataQual = xMetadata.xpath('./dataqual')
|
56
|
+
unless xDataQual.empty?
|
57
|
+
Quality.unpack(xDataQual, hResponseObj)
|
58
|
+
end
|
59
|
+
|
60
|
+
# metadata (spdoinfo 3) - spatial data organization
|
61
|
+
xSpatialOrg = xMetadata.xpath('./spdoinfo')
|
62
|
+
unless xSpatialOrg.empty?
|
63
|
+
SpatialOrganization.unpack(xSpatialOrg, hResponseObj)
|
64
|
+
end
|
65
|
+
|
66
|
+
# metadata (spref 4) - spatial reference
|
67
|
+
xSpatialRef = xMetadata.xpath('./spref')
|
68
|
+
unless xSpatialRef.empty?
|
69
|
+
SpatialReference.unpack(xSpatialRef, hResponseObj)
|
70
|
+
end
|
71
|
+
|
72
|
+
# metadata (eainfo 5) - entity and attribute
|
73
|
+
xEntity = xMetadata.xpath('./eainfo')
|
74
|
+
unless xEntity.empty?
|
75
|
+
EntityAttribute.unpack(xEntity, hResponseObj)
|
76
|
+
end
|
77
|
+
|
78
|
+
# metadata (distinfo 6) - distribution information
|
79
|
+
xDistribution = xMetadata.xpath('./distinfo')
|
80
|
+
unless xDistribution.empty?
|
81
|
+
Distribution.unpack(xDistribution, hResponseObj)
|
82
|
+
end
|
83
|
+
|
84
|
+
# metadata (metainfo 7) - metadata reference (required)
|
85
|
+
xMetaInfo = xMetadata.xpath('./metainfo')
|
86
|
+
unless xMetaInfo.empty?
|
87
|
+
MetadataInformation.unpack(xMetaInfo, hResponseObj)
|
88
|
+
end
|
89
|
+
if xMetaInfo.empty?
|
90
|
+
hResponseObj[:readerExecutionMessages] << 'FGDC is missing metadata information section (metainfo)'
|
91
|
+
end
|
92
|
+
|
93
|
+
return intObj
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
# find the array pointer and type for a contact
|
98
|
+
def self.find_contact_by_id(contactId)
|
99
|
+
contactIndex = nil
|
100
|
+
contactType = nil
|
101
|
+
unless @contacts.empty?
|
102
|
+
@contacts.each_with_index do |contact, i|
|
103
|
+
if contact[:contactId] == contactId
|
104
|
+
if contact[:isOrganization]
|
105
|
+
contactType = 'organization'
|
106
|
+
else
|
107
|
+
contactType = 'individual'
|
108
|
+
end
|
109
|
+
contactIndex = i
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
return contactIndex, contactType
|
114
|
+
end
|
115
|
+
|
116
|
+
# find contact id for a name
|
117
|
+
def self.find_contact_by_name(contactName)
|
118
|
+
@contacts.each do |contact|
|
119
|
+
if contact[:name] == contactName
|
120
|
+
return contact[:contactId]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
return nil
|
124
|
+
end
|
125
|
+
|
126
|
+
# add new contact to contacts array
|
127
|
+
def self.add_contact(name, isOrg)
|
128
|
+
contactId = find_contact_by_name(name)
|
129
|
+
if contactId.nil?
|
130
|
+
intMetadataClass = InternalMetadata.new
|
131
|
+
hContact = intMetadataClass.newContact
|
132
|
+
contactId = UUIDTools::UUID.random_create.to_s
|
133
|
+
hContact[:contactId] = contactId
|
134
|
+
hContact[:name] = name
|
135
|
+
hContact[:isOrganization] = isOrg
|
136
|
+
@contacts << hContact
|
137
|
+
end
|
138
|
+
return contactId
|
139
|
+
end
|
140
|
+
|
141
|
+
# return contact by id
|
142
|
+
def self.get_contact_by_id(contactId)
|
143
|
+
index = find_contact_by_id(contactId)[0]
|
144
|
+
unless index.nil?
|
145
|
+
return @contacts[index]
|
146
|
+
end
|
147
|
+
return nil
|
148
|
+
end
|
149
|
+
|
150
|
+
# add or replace the contact
|
151
|
+
def self.set_contact(hContact)
|
152
|
+
index = find_contact_by_id(hContact[:contactId])[0]
|
153
|
+
if index.nil?
|
154
|
+
@contacts << hContact
|
155
|
+
index = @contacts.length - 1
|
156
|
+
else
|
157
|
+
@contacts[index] = hContact
|
158
|
+
end
|
159
|
+
return index
|
160
|
+
end
|
161
|
+
|
162
|
+
# set an internal object for tests
|
163
|
+
def self.set_intObj(intObj)
|
164
|
+
@intObj = intObj
|
165
|
+
@contacts = @intObj[:contacts]
|
166
|
+
end
|
167
|
+
|
168
|
+
# get internal object for test modules
|
169
|
+
def self.get_intObj
|
170
|
+
return @intObj
|
171
|
+
end
|
172
|
+
|
173
|
+
# get metadata time convention
|
174
|
+
def self.get_metadata_time_convention
|
175
|
+
return @xDoc.xpath('./metadata/metainfo/mettc').text
|
176
|
+
end
|
177
|
+
|
178
|
+
# set @xDoc for minitests
|
179
|
+
def self.set_xDoc(xDoc)
|
180
|
+
@xDoc = xDoc
|
181
|
+
end
|
182
|
+
|
183
|
+
# add new associated resource
|
184
|
+
def self.add_associated_resource(hResource)
|
185
|
+
@intObj[:metadata][:associatedResources] << hResource
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|