883 lines
40 KiB
Python
Raw Normal View History

2016-07-25 11:01:19 -04:00
# -*- coding: ISO-8859-15 -*-
# =============================================================================
# Copyright (c) 2009 Tom Kralidis
#
# Authors : Tom Kralidis <tomkralidis@gmail.com>
# Angelos Tzotsos <tzotsos@gmail.com>
#
# Contact email: tomkralidis@gmail.com
# =============================================================================
""" ISO metadata parser """
2016-07-25 11:01:19 -04:00
from __future__ import (absolute_import, division, print_function)
import warnings
from owslib.etree import etree
from owslib import util
from owslib.namespaces import Namespaces
# default variables
def get_namespaces():
n = Namespaces()
ns = n.get_namespaces(["gco","gmd","gml","gml32","gmx","gts","srv","xlink"])
ns[None] = n.get_namespace("gmd")
return ns
namespaces = get_namespaces()
class MD_Metadata(object):
""" Process gmd:MD_Metadata """
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.xml = None
self.identifier = None
self.parentidentifier = None
self.language = None
self.dataseturi = None
self.languagecode = None
self.datestamp = None
self.charset = None
self.hierarchy = None
self.contact = []
self.datetimestamp = None
self.stdname = None
self.stdver = None
self.referencesystem = None
self.identification = None
self.serviceidentification = None
self.identificationinfo = []
self.distribution = None
self.dataquality = None
else:
if hasattr(md, 'getroot'): # standalone document
self.xml = etree.tostring(md.getroot())
else: # part of a larger document
self.xml = etree.tostring(md)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:fileIdentifier/gco:CharacterString', namespaces))
self.identifier = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:parentIdentifier/gco:CharacterString', namespaces))
self.parentidentifier = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:language/gco:CharacterString', namespaces))
self.language = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:dataSetURI/gco:CharacterString', namespaces))
self.dataseturi = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:language/gmd:LanguageCode', namespaces))
2016-07-25 11:01:19 -04:00
self.languagecode = util.testXMLAttribute(val, 'codeListValue')
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:dateStamp/gco:Date', namespaces))
self.datestamp = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
if not self.datestamp:
val = md.find(util.nspath_eval('gmd:dateStamp/gco:DateTime', namespaces))
self.datestamp = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
self.charset = _testCodeListValue(md.find(util.nspath_eval('gmd:characterSet/gmd:MD_CharacterSetCode', namespaces)))
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.hierarchy = _testCodeListValue(md.find(util.nspath_eval('gmd:hierarchyLevel/gmd:MD_ScopeCode', namespaces)))
2014-09-03 08:43:11 -04:00
self.contact = []
for i in md.findall(util.nspath_eval('gmd:contact/gmd:CI_ResponsibleParty', namespaces)):
o = CI_ResponsibleParty(i)
self.contact.append(o)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:dateStamp/gco:DateTime', namespaces))
self.datetimestamp = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:metadataStandardName/gco:CharacterString', namespaces))
self.stdname = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:metadataStandardVersion/gco:CharacterString', namespaces))
self.stdver = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:referenceSystemInfo/gmd:MD_ReferenceSystem', namespaces))
if val is not None:
self.referencesystem = MD_ReferenceSystem(val)
else:
self.referencesystem = None
2014-09-03 08:43:11 -04:00
# TODO: merge .identificationinfo into .identification
2016-07-25 11:01:19 -04:00
warnings.warn(
'the .identification and .serviceidentification properties will merge into '
'.identification being a list of properties. This is currently implemented '
'in .identificationinfo. '
'Please see https://github.com/geopython/OWSLib/issues/38 for more information',
FutureWarning)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:identificationInfo/gmd:MD_DataIdentification', namespaces))
val2 = md.find(util.nspath_eval('gmd:identificationInfo/srv:SV_ServiceIdentification', namespaces))
2014-09-03 08:43:11 -04:00
if val is not None:
self.identification = MD_DataIdentification(val, 'dataset')
self.serviceidentification = None
elif val2 is not None:
self.identification = MD_DataIdentification(val2, 'service')
self.serviceidentification = SV_ServiceIdentification(val2)
else:
self.identification = None
self.serviceidentification = None
self.identificationinfo = []
for idinfo in md.findall(util.nspath_eval('gmd:identificationInfo', namespaces)):
2016-07-25 11:01:19 -04:00
if len(idinfo) > 0:
val = list(idinfo)[0]
tagval = util.xmltag_split(val.tag)
if tagval == 'MD_DataIdentification':
self.identificationinfo.append(MD_DataIdentification(val, 'dataset'))
elif tagval == 'MD_ServiceIdentification':
self.identificationinfo.append(MD_DataIdentification(val, 'service'))
elif tagval == 'SV_ServiceIdentification':
self.identificationinfo.append(SV_ServiceIdentification(val))
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:distributionInfo/gmd:MD_Distribution', namespaces))
2014-09-03 08:43:11 -04:00
if val is not None:
self.distribution = MD_Distribution(val)
else:
self.distribution = None
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:dataQualityInfo/gmd:DQ_DataQuality', namespaces))
if val is not None:
self.dataquality = DQ_DataQuality(val)
else:
self.dataquality = None
class CI_Date(object):
""" process CI_Date """
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.date = None
self.type = None
else:
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:date/gco:Date', namespaces))
if val is not None:
self.date = util.testXMLValue(val)
else:
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:date/gco:DateTime', namespaces))
if val is not None:
self.date = util.testXMLValue(val)
else:
self.date = None
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:dateType/gmd:CI_DateTypeCode', namespaces))
self.type = _testCodeListValue(val)
class CI_ResponsibleParty(object):
""" process CI_ResponsibleParty """
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.name = None
self.organization = None
self.position = None
self.phone = None
self.fax = None
self.address = None
self.city = None
self.region = None
self.postcode = None
self.country = None
self.email = None
self.onlineresource = None
self.role = None
else:
val = md.find(util.nspath_eval('gmd:individualName/gco:CharacterString', namespaces))
self.name = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:organisationName/gco:CharacterString', namespaces))
self.organization = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:positionName/gco:CharacterString', namespaces))
self.position = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:phone/gmd:CI_Telephone/gmd:voice/gco:CharacterString', namespaces))
2014-09-03 08:43:11 -04:00
self.phone = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:phone/gmd:CI_Telephone/gmd:facsimile/gco:CharacterString', namespaces))
self.fax = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:deliveryPoint/gco:CharacterString', namespaces))
self.address = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:city/gco:CharacterString', namespaces))
self.city = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:administrativeArea/gco:CharacterString', namespaces))
self.region = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:postalCode/gco:CharacterString', namespaces))
self.postcode = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:country/gco:CharacterString', namespaces))
self.country = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:electronicMailAddress/gco:CharacterString', namespaces))
self.email = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:contactInfo/gmd:CI_Contact/gmd:onlineResource/gmd:CI_OnlineResource', namespaces))
if val is not None:
self.onlineresource = CI_OnlineResource(val)
else:
self.onlineresource = None
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.role = _testCodeListValue(md.find(util.nspath_eval('gmd:role/gmd:CI_RoleCode', namespaces)))
2016-07-25 11:01:19 -04:00
class MD_Keywords(object):
"""
Class for the metadata MD_Keywords element
"""
def __init__(self, md=None):
if md is None:
self.keywords = []
self.type = None
self.thesaurus = None
self.kwdtype_codeList = 'http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/codelist/gmxCodelists.xml#MD_KeywordTypeCode'
else:
self.keywords = []
val = md.findall(util.nspath_eval('gmd:keyword/gco:CharacterString', namespaces))
for word in val:
self.keywords.append(util.testXMLValue(word))
self.type = None
val = md.find(util.nspath_eval('gmd:type/gmd:MD_KeywordTypeCode', namespaces))
self.type = util.testXMLAttribute(val, 'codeListValue')
self.thesaurus = None
val = md.find(util.nspath_eval('gmd:thesaurusName/gmd:CI_Citation', namespaces))
if val is not None:
self.thesaurus = {}
thesaurus = val.find(util.nspath_eval('gmd:title/gco:CharacterString', namespaces))
self.thesaurus['title'] = util.testXMLValue(thesaurus)
thesaurus = val.find(util.nspath_eval('gmd:date/gmd:CI_Date/gmd:date/gco:Date', namespaces))
self.thesaurus['date'] = util.testXMLValue(thesaurus)
thesaurus = val.find(util.nspath_eval('gmd:date/gmd:CI_Date/gmd:dateType/gmd:CI_DateTypeCode', namespaces))
self.thesaurus['datetype'] = util.testXMLAttribute(thesaurus, 'codeListValue')
class MD_DataIdentification(object):
""" process MD_DataIdentification """
2014-09-03 08:43:11 -04:00
def __init__(self, md=None, identtype=None):
if md is None:
self.identtype = None
self.title = None
self.alternatetitle = None
self.aggregationinfo = None
self.uricode = []
self.uricodespace = []
self.date = []
self.datetype = []
self.uselimitation = []
2016-07-25 11:01:19 -04:00
self.uselimitation_url = []
2014-09-03 08:43:11 -04:00
self.accessconstraints = []
self.classification = []
self.otherconstraints = []
self.securityconstraints = []
self.useconstraints = []
self.denominators = []
self.distance = []
self.uom = []
self.resourcelanguage = []
2016-07-25 11:01:19 -04:00
self.creator = []
self.publisher = []
self.contributor = []
2014-09-03 08:43:11 -04:00
self.edition = None
self.abstract = None
2016-07-25 11:01:19 -04:00
self.abstract_url = None
2014-09-03 08:43:11 -04:00
self.purpose = None
self.status = None
self.contact = []
self.keywords = []
2016-07-25 11:01:19 -04:00
self.keywords2 = []
2014-09-03 08:43:11 -04:00
self.topiccategory = []
self.supplementalinformation = None
self.extent = None
self.bbox = None
self.temporalextent_start = None
self.temporalextent_end = None
2016-07-25 11:01:19 -04:00
self.spatialrepresentationtype = []
2014-09-03 08:43:11 -04:00
else:
self.identtype = identtype
val = md.find(util.nspath_eval('gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString', namespaces))
self.title = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:citation/gmd:CI_Citation/gmd:alternateTitle/gco:CharacterString', namespaces))
self.alternatetitle = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:aggregationInfo', namespaces))
self.aggregationinfo = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
self.uricode = []
for i in md.findall(util.nspath_eval('gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier/gmd:code/gco:CharacterString', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.uricode.append(val)
2014-09-03 08:43:11 -04:00
self.uricodespace = []
for i in md.findall(util.nspath_eval('gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier/gmd:codeSpace/gco:CharacterString', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.uricodespace.append(val)
2014-09-03 08:43:11 -04:00
self.date = []
self.datetype = []
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
for i in md.findall(util.nspath_eval('gmd:citation/gmd:CI_Citation/gmd:date/gmd:CI_Date', namespaces)):
self.date.append(CI_Date(i))
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.uselimitation = []
2016-07-25 11:01:19 -04:00
self.uselimitation_url = []
2014-09-03 08:43:11 -04:00
for i in md.findall(util.nspath_eval('gmd:resourceConstraints/gmd:MD_Constraints/gmd:useLimitation/gco:CharacterString', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.uselimitation.append(val)
2016-07-25 11:01:19 -04:00
for i in md.findall(util.nspath_eval('gmd:resourceConstraints/gmd:MD_Constraints/gmd:useLimitation/gmx:Anchor', namespaces)):
val = util.testXMLValue(i)
val1 = i.attrib.get(util.nspath_eval('xlink:href', namespaces))
if val is not None:
self.uselimitation.append(val)
self.uselimitation_url.append(val1)
2014-09-03 08:43:11 -04:00
self.accessconstraints = []
for i in md.findall(util.nspath_eval('gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_RestrictionCode', namespaces)):
val = _testCodeListValue(i)
if val is not None:
self.accessconstraints.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.classification = []
for i in md.findall(util.nspath_eval('gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_ClassificationCode', namespaces)):
val = _testCodeListValue(i)
if val is not None:
self.classification.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.otherconstraints = []
for i in md.findall(util.nspath_eval('gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:otherConstraints/gco:CharacterString', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.otherconstraints.append(val)
2014-09-03 08:43:11 -04:00
self.securityconstraints = []
2016-07-25 11:01:19 -04:00
for i in md.findall(util.nspath_eval('gmd:resourceConstraints/gmd:MD_SecurityConstraints/gmd:classification/gmd:MD_ClassificationCode', namespaces)):
2014-09-03 08:43:11 -04:00
val = util.testXMLValue(i)
if val is not None:
self.securityconstraints.append(val)
2014-09-03 08:43:11 -04:00
self.useconstraints = []
for i in md.findall(util.nspath_eval('gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:useConstraints/gmd:MD_RestrictionCode', namespaces)):
val = _testCodeListValue(i)
if val is not None:
self.useconstraints.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.denominators = []
for i in md.findall(util.nspath_eval('gmd:spatialResolution/gmd:MD_Resolution/gmd:equivalentScale/gmd:MD_RepresentativeFraction/gmd:denominator/gco:Integer', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.denominators.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.distance = []
self.uom = []
for i in md.findall(util.nspath_eval('gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.distance.append(val)
self.uom.append(i.get("uom"))
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.resourcelanguage = []
for i in md.findall(util.nspath_eval('gmd:language/gmd:LanguageCode', namespaces)):
val = _testCodeListValue(i)
if val is not None:
self.resourcelanguage.append(val)
2016-07-25 11:01:19 -04:00
self.creator = []
self.publisher = []
self.contributor = []
for val in md.findall(util.nspath_eval('gmd:pointOfContact/gmd:CI_ResponsibleParty', namespaces)):
role = val.find(util.nspath_eval('gmd:role/gmd:CI_RoleCode', namespaces))
if role is not None:
clv = _testCodeListValue(role)
rp = CI_ResponsibleParty(val)
2014-09-03 08:43:11 -04:00
if clv == 'originator':
2016-07-25 11:01:19 -04:00
self.creator.append(rp)
2014-09-03 08:43:11 -04:00
elif clv == 'publisher':
2016-07-25 11:01:19 -04:00
self.publisher.append(rp)
elif clv == 'author':
self.contributor.append(rp)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:edition/gco:CharacterString', namespaces))
self.edition = util.testXMLValue(val)
val = md.find(util.nspath_eval('gmd:abstract/gco:CharacterString', namespaces))
self.abstract = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
val = md.find(util.nspath_eval('gmd:abstract/gmx:Anchor', namespaces))
if val is not None:
self.abstract = util.testXMLValue(val)
self.abstract_url = val.attrib.get(util.nspath_eval('xlink:href', namespaces))
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:purpose/gco:CharacterString', namespaces))
self.purpose = util.testXMLValue(val)
self.status = _testCodeListValue(md.find(util.nspath_eval('gmd:status/gmd:MD_ProgressCode', namespaces)))
self.contact = []
for i in md.findall(util.nspath_eval('gmd:pointOfContact/gmd:CI_ResponsibleParty', namespaces)):
o = CI_ResponsibleParty(i)
self.contact.append(o)
2016-07-25 11:01:19 -04:00
self.spatialrepresentationtype = []
for val in md.findall(util.nspath_eval('gmd:spatialRepresentationType/gmd:MD_SpatialRepresentationTypeCode', namespaces)):
val = util.testXMLAttribute(val, 'codeListValue')
if val:
self.spatialrepresentationtype.append(val)
warnings.warn(
'The .keywords and .keywords2 properties will merge into the '
'.keywords property in the future, with .keywords becoming a list '
'of MD_Keywords instances. This is currently implemented in .keywords2. '
'Please see https://github.com/geopython/OWSLib/issues/301 for more information',
FutureWarning)
2014-09-03 08:43:11 -04:00
self.keywords = []
2014-09-03 08:43:11 -04:00
for i in md.findall(util.nspath_eval('gmd:descriptiveKeywords', namespaces)):
mdkw = {}
mdkw['type'] = _testCodeListValue(i.find(util.nspath_eval('gmd:MD_Keywords/gmd:type/gmd:MD_KeywordTypeCode', namespaces)))
2014-09-03 08:43:11 -04:00
mdkw['thesaurus'] = {}
2014-09-03 08:43:11 -04:00
val = i.find(util.nspath_eval('gmd:MD_Keywords/gmd:thesaurusName/gmd:CI_Citation/gmd:title/gco:CharacterString', namespaces))
mdkw['thesaurus']['title'] = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = i.find(util.nspath_eval('gmd:MD_Keywords/gmd:thesaurusName/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:date/gco:Date', namespaces))
mdkw['thesaurus']['date'] = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = i.find(util.nspath_eval('gmd:MD_Keywords/gmd:thesaurusName/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:dateType/gmd:CI_DateTypeCode', namespaces))
mdkw['thesaurus']['datetype'] = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
mdkw['keywords'] = []
2014-09-03 08:43:11 -04:00
for k in i.findall(util.nspath_eval('gmd:MD_Keywords/gmd:keyword', namespaces)):
val = k.find(util.nspath_eval('gco:CharacterString', namespaces))
if val is not None:
2016-07-25 11:01:19 -04:00
val2 = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
if val2 is not None:
mdkw['keywords'].append(val2)
self.keywords.append(mdkw)
2016-07-25 11:01:19 -04:00
self.keywords2 = []
for mdkw in md.findall(util.nspath_eval('gmd:descriptiveKeywords/gmd:MD_Keywords', namespaces)):
self.keywords2.append(MD_Keywords(mdkw))
2014-09-03 08:43:11 -04:00
self.topiccategory = []
for i in md.findall(util.nspath_eval('gmd:topicCategory/gmd:MD_TopicCategoryCode', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.topiccategory.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:supplementalInformation/gco:CharacterString', namespaces))
self.supplementalinformation = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
# There may be multiple geographicElement, create an extent
# from the one containing either an EX_GeographicBoundingBox or EX_BoundingPolygon.
# The schema also specifies an EX_GeographicDescription. This is not implemented yet.
val = None
val2 = None
val3 = None
extents = md.findall(util.nspath_eval('gmd:extent', namespaces))
extents.extend(md.findall(util.nspath_eval('srv:extent', namespaces)))
for extent in extents:
if val is None:
for e in extent.findall(util.nspath_eval('gmd:EX_Extent/gmd:geographicElement', namespaces)):
if e.find(util.nspath_eval('gmd:EX_GeographicBoundingBox', namespaces)) is not None or e.find(util.nspath_eval('gmd:EX_BoundingPolygon', namespaces)) is not None:
val = e
break
self.extent = EX_Extent(val)
self.bbox = self.extent.boundingBox # for backwards compatibility
if val2 is None:
val2 = extent.find(util.nspath_eval('gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:beginPosition', namespaces))
if val2 is None:
val2 = extent.find(util.nspath_eval('gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml32:TimePeriod/gml32:beginPosition', namespaces))
self.temporalextent_start = util.testXMLValue(val2)
if val3 is None:
val3 = extent.find(util.nspath_eval('gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:endPosition', namespaces))
if val3 is None:
val3 = extent.find(util.nspath_eval('gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml32:TimePeriod/gml32:endPosition', namespaces))
self.temporalextent_end = util.testXMLValue(val3)
2016-07-25 11:01:19 -04:00
class MD_Distributor(object):
""" process MD_Distributor """
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.contact = None
self.online = []
else:
self.contact = None
val = md.find(util.nspath_eval('gmd:MD_Distributor/gmd:distributorContact/gmd:CI_ResponsibleParty', namespaces))
if val is not None:
self.contact = CI_ResponsibleParty(val)
2014-09-03 08:43:11 -04:00
self.online = []
2014-09-03 08:43:11 -04:00
for ol in md.findall(util.nspath_eval('gmd:MD_Distributor/gmd:distributorTransferOptions/gmd:MD_DigitalTransferOptions/gmd:onLine/gmd:CI_OnlineResource', namespaces)):
self.online.append(CI_OnlineResource(ol))
class MD_Distribution(object):
""" process MD_Distribution """
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.format = None
self.version = None
self.distributor = []
self.online = []
pass
else:
val = md.find(util.nspath_eval('gmd:distributionFormat/gmd:MD_Format/gmd:name/gco:CharacterString', namespaces))
self.format = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:distributionFormat/gmd:MD_Format/gmd:version/gco:CharacterString', namespaces))
self.version = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
self.distributor = []
for dist in md.findall(util.nspath_eval('gmd:distributor', namespaces)):
self.distributor.append(MD_Distributor(dist))
2014-09-03 08:43:11 -04:00
self.online = []
2014-09-03 08:43:11 -04:00
for ol in md.findall(util.nspath_eval('gmd:transferOptions/gmd:MD_DigitalTransferOptions/gmd:onLine/gmd:CI_OnlineResource', namespaces)):
self.online.append(CI_OnlineResource(ol))
2016-07-25 11:01:19 -04:00
class DQ_DataQuality(object):
''' process DQ_DataQuality'''
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.conformancetitle = []
self.conformancedate = []
self.conformancedatetype = []
self.conformancedegree = []
self.lineage = None
2016-07-25 11:01:19 -04:00
self.lineage_url = None
2014-09-03 08:43:11 -04:00
self.specificationtitle = None
self.specificationdate = []
else:
self.conformancetitle = []
for i in md.findall(util.nspath_eval('gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:title/gco:CharacterString', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.conformancetitle.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.conformancedate = []
for i in md.findall(util.nspath_eval('gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:date/gco:Date', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.conformancedate.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.conformancedatetype = []
for i in md.findall(util.nspath_eval('gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:dateType/gmd:CI_DateTypeCode', namespaces)):
val = _testCodeListValue(i)
if val is not None:
self.conformancedatetype.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.conformancedegree = []
for i in md.findall(util.nspath_eval('gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:pass/gco:Boolean', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.conformancedegree.append(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:lineage/gmd:LI_Lineage/gmd:statement/gco:CharacterString', namespaces))
self.lineage = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
val = md.find(util.nspath_eval('gmd:lineage/gmd:LI_Lineage/gmd:statement/gmx:Anchor', namespaces))
if val is not None:
self.lineage = util.testXMLValue(val)
self.lineage_url = val.attrib.get(util.nspath_eval('xlink:href', namespaces))
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:title/gco:CharacterString', namespaces))
self.specificationtitle = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
self.specificationdate = []
for i in md.findall(util.nspath_eval('gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:date/gmd:CI_Date', namespaces)):
val = util.testXMLValue(i)
if val is not None:
self.specificationdate.append(val)
class SV_ServiceIdentification(object):
""" process SV_ServiceIdentification """
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
2016-07-25 11:01:19 -04:00
self.title = None
self.abstract = None
self.contact = None
2014-09-03 08:43:11 -04:00
self.identtype = 'service'
self.type = None
self.version = None
self.fees = None
self.bbox = None
2016-07-25 11:01:19 -04:00
self.couplingtype = None
2014-09-03 08:43:11 -04:00
self.operations = []
self.operateson = []
else:
2016-07-25 11:01:19 -04:00
val = md.find(util.nspath_eval('gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString', namespaces))
self.title=util.testXMLValue(val)
val = md.find(util.nspath_eval('gmd:abstract/gco:CharacterString', namespaces))
self.abstract = util.testXMLValue(val)
self.contact = None
val = md.find(util.nspath_eval('gmd:citation/gmd:CI_Citation/gmd:citedResponsibleParty/gmd:CI_ResponsibleParty', namespaces))
if val is not None:
self.contact = CI_ResponsibleParty(val)
2014-09-03 08:43:11 -04:00
self.identtype = 'service'
val = md.find(util.nspath_eval('srv:serviceType/gco:LocalName', namespaces))
self.type = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('srv:serviceTypeVersion/gco:CharacterString', namespaces))
self.version = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('srv:accessProperties/gmd:MD_StandardOrderProcess/gmd:fees/gco:CharacterString', namespaces))
self.fees = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('srv:extent/gmd:EX_Extent', namespaces))
2014-09-03 08:43:11 -04:00
if val is not None:
self.bbox = EX_Extent(val)
else:
self.bbox = None
self.couplingtype = _testCodeListValue(md.find(util.nspath_eval('gmd:couplingType/gmd:SV_CouplingType', namespaces)))
self.operations = []
for i in md.findall(util.nspath_eval('srv:containsOperations', namespaces)):
tmp = {}
val = i.find(util.nspath_eval('srv:SV_OperationMetadata/srv:operationName/gco:CharacterString', namespaces))
tmp['name'] = util.testXMLValue(val)
tmp['dcplist'] = []
for d in i.findall(util.nspath_eval('srv:SV_OperationMetadata/srv:DCP', namespaces)):
tmp2 = _testCodeListValue(d.find(util.nspath_eval('srv:DCPList', namespaces)))
tmp['dcplist'].append(tmp2)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
tmp['connectpoint'] = []
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
for d in i.findall(util.nspath_eval('srv:SV_OperationMetadata/srv:connectPoint', namespaces)):
tmp3 = d.find(util.nspath_eval('gmd:CI_OnlineResource', namespaces))
tmp['connectpoint'].append(CI_OnlineResource(tmp3))
self.operations.append(tmp)
self.operateson = []
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
for i in md.findall(util.nspath_eval('srv:operatesOn', namespaces)):
tmp = {}
tmp['uuidref'] = i.attrib.get('uuidref')
tmp['href'] = i.attrib.get(util.nspath_eval('xlink:href', namespaces))
tmp['title'] = i.attrib.get(util.nspath_eval('xlink:title', namespaces))
self.operateson.append(tmp)
class CI_OnlineResource(object):
""" process CI_OnlineResource """
2014-09-03 08:43:11 -04:00
def __init__(self,md=None):
if md is None:
self.url = None
self.protocol = None
self.name = None
self.description = None
self.function = None
else:
val = md.find(util.nspath_eval('gmd:linkage/gmd:URL', namespaces))
self.url = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:protocol/gco:CharacterString', namespaces))
self.protocol = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:name/gco:CharacterString', namespaces))
self.name = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:description/gco:CharacterString', namespaces))
self.description = util.testXMLValue(val)
2014-09-03 08:43:11 -04:00
self.function = _testCodeListValue(md.find(util.nspath_eval('gmd:function/gmd:CI_OnLineFunctionCode', namespaces)))
class EX_GeographicBoundingBox(object):
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.minx = None
self.maxx = None
self.miny = None
self.maxy = None
else:
val = md.find(util.nspath_eval('gmd:westBoundLongitude/gco:Decimal', namespaces))
self.minx = util.testXMLValue(val)
val = md.find(util.nspath_eval('gmd:eastBoundLongitude/gco:Decimal', namespaces))
self.maxx = util.testXMLValue(val)
val = md.find(util.nspath_eval('gmd:southBoundLatitude/gco:Decimal', namespaces))
self.miny = util.testXMLValue(val)
val = md.find(util.nspath_eval('gmd:northBoundLatitude/gco:Decimal', namespaces))
self.maxy = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
class EX_Polygon(object):
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.exterior_ring = None
self.interior_rings = []
else:
linear_ring = md.find(util.nspath_eval('gml32:Polygon/gml32:exterior/gml32:LinearRing', namespaces))
if linear_ring is not None:
self.exterior_ring = self._coordinates_for_ring(linear_ring)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
interior_ring_elements = md.findall(util.nspath_eval('gml32:Polygon/gml32:interior', namespaces))
self.interior_rings = []
for iring_element in interior_ring_elements:
linear_ring = iring_element.find(util.nspath_eval('gml32:LinearRing', namespaces))
self.interior_rings.append(self._coordinates_for_ring(linear_ring))
2016-07-25 11:01:19 -04:00
def _coordinates_for_ring(self, linear_ring):
coordinates = []
positions = linear_ring.findall(util.nspath_eval('gml32:pos', namespaces))
for pos in positions:
tokens = pos.text.split()
coords = tuple([float(t) for t in tokens])
coordinates.append(coords)
return coordinates
2016-07-25 11:01:19 -04:00
class EX_GeographicBoundingPolygon(object):
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
2016-07-25 11:01:19 -04:00
self.is_extent = None
2014-09-03 08:43:11 -04:00
self.polygons = []
else:
val = md.find(util.nspath_eval('gmd:extentTypeCode', namespaces))
self.is_extent = util.testXMLValue(val)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
md_polygons = md.findall(util.nspath_eval('gmd:polygon', namespaces))
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
self.polygons = []
for val in md_polygons:
self.polygons.append(EX_Polygon(val))
2016-07-25 11:01:19 -04:00
class EX_Extent(object):
""" process EX_Extent """
2014-09-03 08:43:11 -04:00
def __init__(self, md=None):
if md is None:
self.boundingBox = None
self.boundingPolygon = None
self.description_code = None
else:
self.boundingBox = None
self.boundingPolygon = None
2014-09-03 08:43:11 -04:00
if md is not None:
bboxElement = md.find(util.nspath_eval('gmd:EX_GeographicBoundingBox', namespaces))
if bboxElement is not None:
self.boundingBox = EX_GeographicBoundingBox(bboxElement)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
polygonElement = md.find(util.nspath_eval('gmd:EX_BoundingPolygon', namespaces))
if polygonElement is not None:
self.boundingPolygon = EX_GeographicBoundingPolygon(polygonElement)
2016-07-25 11:01:19 -04:00
2014-09-03 08:43:11 -04:00
val = md.find(util.nspath_eval('gmd:EX_GeographicDescription/gmd:geographicIdentifier/gmd:MD_Identifier/gmd:code/gco:CharacterString', namespaces))
self.description_code = util.testXMLValue(val)
class MD_ReferenceSystem(object):
""" process MD_ReferenceSystem """
2016-07-25 11:01:19 -04:00
def __init__(self, md=None):
2014-09-03 08:43:11 -04:00
if md is None:
2016-07-25 11:01:19 -04:00
self.code = None
self.codeSpace = None
self.version = None
2014-09-03 08:43:11 -04:00
else:
val = md.find(util.nspath_eval('gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:code/gco:CharacterString', namespaces))
2016-07-25 11:01:19 -04:00
if val is not None:
self.code = util.testXMLValue(val)
else:
self.code = None
val = md.find(util.nspath_eval('gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:codeSpace/gco:CharacterString', namespaces))
if val is not None:
self.codeSpace = util.testXMLValue(val)
else:
self.codeSpace = None
val = md.find(util.nspath_eval('gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:version/gco:CharacterString', namespaces))
if val is not None:
self.version = util.testXMLValue(val)
else:
self.version = None
def _testCodeListValue(elpath):
""" get gco:CodeListValue_Type attribute, else get text content """
if elpath is not None: # try to get @codeListValue
val = util.testXMLValue(elpath.attrib.get('codeListValue'), True)
if val is not None:
return val
else: # see if there is element text
return util.testXMLValue(elpath)
else:
return None
class CodelistCatalogue(object):
""" process CT_CodelistCatalogue """
def __init__(self, ct):
val = ct.find(util.nspath_eval('gmx:name/gco:CharacterString', namespaces))
self.name = util.testXMLValue(val)
val = ct.find(util.nspath_eval('gmx:scope/gco:CharacterString', namespaces))
self.scope = util.testXMLValue(val)
val = ct.find(util.nspath_eval('gmx:fieldOfApplication/gco:CharacterString', namespaces))
self.fieldapp = util.testXMLValue(val)
val = ct.find(util.nspath_eval('gmx:versionNumber/gco:CharacterString', namespaces))
self.version = util.testXMLValue(val)
val = ct.find(util.nspath_eval('gmx:versionDate/gco:Date', namespaces))
self.date = util.testXMLValue(val)
self.dictionaries = {}
for i in ct.findall(util.nspath_eval('gmx:codelistItem/gmx:CodeListDictionary', namespaces)):
id = i.attrib.get(util.nspath_eval('gml32:id', namespaces))
self.dictionaries[id] = {}
val = i.find(util.nspath_eval('gml32:description', namespaces))
self.dictionaries[id]['description'] = util.testXMLValue(val)
val = i.find(util.nspath_eval('gml32:identifier', namespaces))
self.dictionaries[id]['identifier'] = util.testXMLValue(val)
self.dictionaries[id]['entries'] = {}
for j in i.findall(util.nspath_eval('gmx:codeEntry', namespaces)):
id2 = j.find(util.nspath_eval('gmx:CodeDefinition', namespaces)).attrib.get(util.nspath_eval('gml32:id', namespaces))
self.dictionaries[id]['entries'][id2] = {}
val = j.find(util.nspath_eval('gmx:CodeDefinition/gml32:description', namespaces))
self.dictionaries[id]['entries'][id2]['description'] = util.testXMLValue(val)
val = j.find(util.nspath_eval('gmx:CodeDefinition/gml32:identifier', namespaces))
self.dictionaries[id]['entries'][id2]['identifier'] = util.testXMLValue(val)
val = j.find(util.nspath_eval('gmx:CodeDefinition', namespaces)).attrib.get('codeSpace')
self.dictionaries[id]['entries'][id2]['codespace'] = util.testXMLValue(val, True)
def getcodelistdictionaries(self):
2016-07-25 11:01:19 -04:00
return list(self.dictionaries.keys())
def getcodedefinitionidentifiers(self, cdl):
2016-07-25 11:01:19 -04:00
if cdl in self.dictionaries:
ids = []
for i in self.dictionaries[cdl]['entries']:
ids.append(self.dictionaries[cdl]['entries'][i]['identifier'])
return ids
else:
return None