From 346f0c49dee593200170c03926cb1e9f81ab33b6 Mon Sep 17 00:00:00 2001 From: Johnathan Aspinwall Date: Tue, 25 Jun 2024 11:21:47 -0600 Subject: [PATCH] feat: Add metadata extension section for taxonomy info. --- .../classes/class_enumerationList.rb | 52 +++++ .../iso19115_3/classes/class_extension.rb | 208 ++++++++++++++++++ .../iso19115_3/classes/class_mdMetadata.rb | 24 ++ .../testData/19115_3_mdMetadata.xml | 57 +++++ 4 files changed, 341 insertions(+) create mode 100755 lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_enumerationList.rb create mode 100644 lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_extension.rb diff --git a/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_enumerationList.rb b/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_enumerationList.rb new file mode 100755 index 00000000..f240dc4e --- /dev/null +++ b/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_enumerationList.rb @@ -0,0 +1,52 @@ +# ISO <> Enumerations +# 19115-2 writer output in XML + +# History: +# Stan Smith 2016-12-12 refactored for mdTranslator/mdJson 2.0 +# Stan Smith 2015-07-14 refactored to eliminate namespace globals $WriterNS and $IsoNS +# Stan Smith 2015-07-14 refactored to make iso19110 independent of iso19115_2 classes +# Stan Smith 2015-06-22 replace global ($response) with passed in object (responseObj) +# Stan Smith 2015-06-12 refactored to use mdCodes gem for codelist contents +# Stan Smith 2014-12-15 replaced NOAA CT_CodelistCatalogue with mdTranslator CT_CodelistCatalogue +# Stan Smith 2014-12-12 refactored to handle namespacing readers and writers +# Stan Smith 2014-10-15 allow non-ISO codesNames to be rendered +# Stan Smith 2013-08-09 original script + +require 'adiwg-mdcodes' + +module ADIWG + module Mdtranslator + module Writers + module Iso19115_3 + + class MD_EnumerationList + + def initialize(xml, responseObj) + @xml = xml + @hResponseObj = responseObj + end + + def writeXML(codeList, codeName) + + # get requested codelist from the adiwg-mdcodes gem + mdCodelist = ADIWG::Mdcodes.getCodelistDetail(codeList) + + sourceName = mdCodelist['sourceName'] + codelist = mdCodelist['codelist'] + + # search the codelist for a matching codeName + # only valid enumeration values can be written in ISO + codelist.each do |code| + if code['codeName'] == codeName + @xml.tag!('gmd:' + "#{sourceName}", codeName) + break + end + end + + end # writeXML + end # MD_EnumerationList class + + end + end + end +end diff --git a/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_extension.rb b/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_extension.rb new file mode 100644 index 00000000..d56d28b0 --- /dev/null +++ b/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_extension.rb @@ -0,0 +1,208 @@ +# ISO <> MD_MetadataExtensionInformation +# 19115-2 writer output in XML + +# History: +# Stan Smith 2019-03-22 replaced Enumeration class with method +# Stan Smith 2018-04-09 add error and warning messaging +# Stan Smith 2015-07-14 refactored to eliminate namespace globals $WriterNS and $IsoNS +# Stan Smith 2015-07-14 refactored to make iso19110 independent of iso19115_2 classes +# Stan Smith 2015-06-22 replace global ($response) with passed in object (hResponseObj) +# Stan Smith 2015-06-11 change all codelists to use 'class_codelist' method +# Stan Smith 2014-12-12 refactored to handle namespacing readers and writers +# Stan Smith 2014-07-08 modify require statements to function in RubyGem structure +# Stan Smith 2013-11-22 original script. + +require 'adiwg/mdtranslator/internal/module_codelistFun' +require_relative '../iso19115_3_writer' +require_relative 'class_codelist' +require_relative 'class_enumerationList' +require_relative 'class_onlineResource' + +module ADIWG + module Mdtranslator + module Writers + module Iso19115_3 + + class MD_MetadataExtensionInformation + + def initialize(xml, hResponseObj) + @xml = xml + @hResponseObj = hResponseObj + @NameSpace = ADIWG::Mdtranslator::Writers::Iso19115_3 + end + + def writeXML(hExtension) + + # classes used + codelistClass = MD_Codelist.new(@xml, @hResponseObj) + olResClass = CI_OnlineResource.new(@xml, @hResponseObj) + + outContext = 'extension information' + outContext = 'extension name ' + hExtension[:name] unless hExtension[:name].nil? + + @xml.tag!('gmd:MD_MetadataExtensionInformation') do + + # metadata extension - online resource {CI_OnLineResource} + hOLResource = hExtension[:onLineResource] + unless hOLResource.empty? + @xml.tag!('gmd:extensionOnLineResource') do + olResClass.writeXML(hOLResource, outContext) + end + end + if hOLResource.empty? && @hResponseObj[:writerShowTags] + @xml.tag!('gmd:extensionOnLineResource') + end + + # metadata extension = extended element information + @xml.tag!('gmd:extendedElementInformation') do + @xml.tag!('gmd:MD_ExtendedElementInformation') do + + # extended element info - name (required) + s = hExtension[:name] + unless s.nil? + @xml.tag!('gmd:name') do + @xml.tag!('gco:CharacterString', s) + end + end + if s.nil? + @NameSpace.issueWarning(100, 'gmd:name') + end + + # extended element info - short name + s = hExtension[:shortName] + unless s.nil? + @xml.tag!('gmd:shortName') do + @xml.tag!('gco:CharacterString', s) + end + end + if s.nil? && @hResponseObj[:writerShowTags] + @xml.tag!('gmd:shortName') + end + + # extended element info - definition (required) + s = hExtension[:definition] + unless s.nil? + @xml.tag!('gmd:definition') do + @xml.tag!('gco:CharacterString', s) + end + end + if s.nil? + @NameSpace.issueWarning(101, 'gmd:definition', outContext) + end + + # extended element info - obligation {MD_ObligationCode} + obligation = hExtension[:obligation] + unless obligation.nil? + if CodelistFun.validateItem('iso_obligation', obligation) + @xml.tag!('gmd:obligation') do + @xml.tag!('gmd:MD_ObligationCode', obligation) + end + else + @NameSpace.issueWarning(380, 'gmd:obligation', "#{obligation}") + end + end + if obligation.nil? && @hResponseObj[:writerShowTags] + @xml.tag!('gmd:obligation') + end + + # extended element info - data type (required) + s = hExtension[:dataType] + unless s.nil? + @xml.tag!('gmd:dataType') do + codelistClass.writeXML('gmd', 'iso_entityClass', s) + end + end + if s.nil? + @NameSpace.issueWarning(102, 'gmd:dataType', outContext) + end + + # extended element info - maximum occurrence + s = hExtension[:maxOccurrence] + unless s.nil? + @xml.tag!('gmd:maximumOccurrence') do + @xml.tag!('gco:CharacterString', s) + end + end + if s.nil? && @hResponseObj[:writerShowTags] + @xml.tag!('gmd:maximumOccurrence') + end + + # extended element info - parent entity [] (required) + aParents = hExtension[:parentEntities] + aParents.each do |parent| + @xml.tag!('gmd:parentEntity') do + @xml.tag!('gco:CharacterString', parent) + end + end + if aParents.empty? + @NameSpace.issueWarning(103, 'gmd:parentEntity', outContext) + end + + # extended element info - rule + s = hExtension[:rule] + unless s.nil? + @xml.tag!('gmd:rule') do + @xml.tag!('gco:CharacterString', s) + end + end + if s.nil? + @NameSpace.issueWarning(104, 'gmd:rule', outContext) + end + + # extended element info - rationale [] + aRations = hExtension[:rationales] + aRations.each do |ration| + @xml.tag!('gmd:rationale') do + @xml.tag!('gco:CharacterString', ration) + end + end + if aRations.empty? && @hResponseObj[:writerShowTags] + @xml.tag!('gmd:rationale') + end + + # extended element info - source [] (required) + # only allowing 1 for now + role = hExtension[:sourceRole] + unless role.nil? + @xml.tag!('gmd:source') do + @xml.tag!('gmd:CI_ResponsibleParty') do + orgName = hExtension[:sourceOrganization] + unless orgName.nil? + @xml.tag!('gmd:organisationName') do + @xml.tag!('gco:CharacterString', orgName) + end + end + uri = hExtension[:sourceURI] + unless uri.nil? + @xml.tag!('gmd:contactInfo') do + @xml.tag!('gmd:CI_Contact') do + @xml.tag!('gmd:onlineResource') do + @xml.tag!('gmd:CI_OnlineResource') do + @xml.tag!('gmd:linkage') do + @xml.tag!('gmd:URL', uri) + end + end + end + end + end + end + @xml.tag!('gmd:role') do + codelistClass.writeXML('gmd', 'iso_role', role) + end + end + end + end + if role.nil? + @NameSpace.issueWarning(105, 'gmd:source', outContext) + end + + end # gmd:MD_ExtendedElementInformation tag + end # gmd:extendedElementInformation + end # gmd:MD_MetadataExtensionInformation + end # writeXML + end # MD_MetadataExtensionInformation class + + end + end + end +end diff --git a/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_mdMetadata.rb b/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_mdMetadata.rb index c6657190..1924977c 100644 --- a/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_mdMetadata.rb +++ b/lib/adiwg/mdtranslator/writers/iso19115_3/classes/class_mdMetadata.rb @@ -26,6 +26,7 @@ require_relative 'class_spatialRepresentation' require_relative 'class_referenceSystem' require_relative 'class_featureCatalog' +require_relative 'class_extension' module ADIWG module Mdtranslator @@ -62,6 +63,7 @@ def writeXML(intObj) representationClass = SpatialRepresentation.new(@xml, @hResponseObj) referenceSystemClass = MD_ReferenceSystem.new(@xml, @hResponseObj) mdCatalogClass = MD_FeatureCatalogue.new(@xml, @hResponseObj) + extensionClass = MD_MetadataExtensionInformation.new(@xml, @hResponseObj) # create shortcuts to sections of internal object hMetadata = intObj[:metadata] @@ -291,6 +293,28 @@ def writeXML(intObj) @xml.tag!('mdb:referenceSystemInfo') end + # metadata information - metadata extension info + # add biological profile to all metadata records + intBio = intMetadataClass.newMetadataExtension + intBio[:name] = 'Taxonomy System' + intBio[:shortName] = 'TaxonSys' + intBio[:definition] = 'Documentation of taxonomic sources, procedures, and treatments' + intBio[:obligation] = 'optional' + intBio[:dataType] = 'class' + intBio[:maxOccurrence] = '1' + intBio[:parentEntities] << 'MD_Identification' + intBio[:rule] = 'New Metadata section as a class to MD_Identification' + intBio[:rationales] << 'The set of data elements contained within this class element ' + + 'represents an attempt to provide better documentation of ' + + 'taxonomic sources, procedures, and treatments.' + intBio[:sourceOrganization] = 'National Biological Information Infrastructure' + intBio[:sourceURI] = 'https://www2.usgs.gov/core_science_systems/Access/p1111-1.html' + intBio[:sourceRole] = 'author' + + @xml.tag!('gmd:metadataExtensionInfo') do + extensionClass.writeXML(intBio) + end + # ###################### Begin Data Identification ##################### # metadata information - data identification info - required diff --git a/test/writers/iso19115-3/testData/19115_3_mdMetadata.xml b/test/writers/iso19115-3/testData/19115_3_mdMetadata.xml index 6bd5b89a..93e54424 100644 --- a/test/writers/iso19115-3/testData/19115_3_mdMetadata.xml +++ b/test/writers/iso19115-3/testData/19115_3_mdMetadata.xml @@ -155,6 +155,63 @@ + + + + + + + Taxonomy System + + + TaxonSys + + + Documentation of taxonomic sources, procedures, and treatments + + + optional + + + + + + 1 + + + MD_Identification + + + New Metadata section as a class to MD_Identification + + + The set of data elements contained within this class element represents an attempt to provide better documentation of taxonomic sources, procedures, and treatments. + + + + + National Biological Information Infrastructure + + + + + + + https://www2.usgs.gov/core_science_systems/Access/p1111-1.html + + + + + + + + + + + + + +