Source code for gws.common.metadata
"""Utilities to manipulate metadata"""
import gws
import gws.tools.country
import gws.tools.date
import gws.types as t
from . import inspire
#:export
[docs]class MetaInspireTheme(t.Enum):
"""Inspire theme, see http://inspire.ec.europa.eu/theme/"""
ac = 'ac' #: Atmospheric conditions
ad = 'ad' #: Addresses
af = 'af' #: Agricultural and aquaculture facilities
am = 'am' #: Area management/restriction/regulation zones and reporting units
au = 'au' #: Administrative units
br = 'br' #: Bio-geographical regions
bu = 'bu' #: Buildings
cp = 'cp' #: Cadastral parcels
ef = 'ef' #: Environmental monitoring facilities
el = 'el' #: Elevation
er = 'er' #: Energy resources
ge = 'ge' #: Geology
gg = 'gg' #: Geographical grid systems
gn = 'gn' #: Geographical names
hb = 'hb' #: Habitats and biotopes
hh = 'hh' #: Human health and safety
hy = 'hy' #: Hydrography
lc = 'lc' #: Land cover
lu = 'lu' #: Land use
mf = 'mf' #: Meteorological geographical features
mr = 'mr' #: Mineral resources
nz = 'nz' #: Natural risk zones
of = 'of' #: Oceanographic geographical features
oi = 'oi' #: Orthoimagery
pd = 'pd' #: Population distribution — demography
pf = 'pf' #: Production and industrial facilities
ps = 'ps' #: Protected sites
rs = 'rs' #: Coordinate reference systems
sd = 'sd' #: Species distribution
so = 'so' #: Soil
sr = 'sr' #: Sea regions
su = 'su' #: Statistical units
tn = 'tn' #: Transport networks
us = 'us' #: Utility and governmental services
#:export
[docs]class MetaInspireResourceType(t.Enum):
"""Inspire resourceType, see http://inspire.ec.europa.eu/schemas/common/1.0/common.xsd"""
dataset = 'dataset'
series = 'series'
service = 'service'
#:export
[docs]class MetaInspireSpatialDataServiceType(t.Enum):
"""Inspire spatialDataServiceType, see http://inspire.ec.europa.eu/schemas/common/1.0/common.xsd"""
discovery = 'discovery'
view = 'view'
download = 'download'
transformation = 'transformation'
invoke = 'invoke'
other = 'other'
#:export
[docs]class MetaInspireDegreeOfConformity(t.Enum):
"""Inspire degreeOfConformity, see http://inspire.ec.europa.eu/schemas/common/1.0/common.xsd"""
conformant = 'conformant'
notConformant = 'notConformant'
notEvaluated = 'notEvaluated'
#:export
[docs]class MetaInspireMandatoryKeyword(t.Enum):
"""Inspire keyword, see http://inspire.ec.europa.eu/schemas/common/1.0/common.xsd"""
chainDefinitionService = 'chainDefinitionService'
comEncodingService = 'comEncodingService'
comGeographicCompressionService = 'comGeographicCompressionService'
comGeographicFormatConversionService = 'comGeographicFormatConversionService'
comMessagingService = 'comMessagingService'
comRemoteFileAndExecutableManagement = 'comRemoteFileAndExecutableManagement'
comService = 'comService'
comTransferService = 'comTransferService'
humanCatalogueViewer = 'humanCatalogueViewer'
humanChainDefinitionEditor = 'humanChainDefinitionEditor'
humanFeatureGeneralizationEditor = 'humanFeatureGeneralizationEditor'
humanGeographicDataStructureViewer = 'humanGeographicDataStructureViewer'
humanGeographicFeatureEditor = 'humanGeographicFeatureEditor'
humanGeographicSpreadsheetViewer = 'humanGeographicSpreadsheetViewer'
humanGeographicSymbolEditor = 'humanGeographicSymbolEditor'
humanGeographicViewer = 'humanGeographicViewer'
humanInteractionService = 'humanInteractionService'
humanServiceEditor = 'humanServiceEditor'
humanWorkflowEnactmentManager = 'humanWorkflowEnactmentManager'
infoCatalogueService = 'infoCatalogueService'
infoCoverageAccessService = 'infoCoverageAccessService'
infoFeatureAccessService = 'infoFeatureAccessService'
infoFeatureTypeService = 'infoFeatureTypeService'
infoGazetteerService = 'infoGazetteerService'
infoManagementService = 'infoManagementService'
infoMapAccessService = 'infoMapAccessService'
infoOrderHandlingService = 'infoOrderHandlingService'
infoProductAccessService = 'infoProductAccessService'
infoRegistryService = 'infoRegistryService'
infoSensorDescriptionService = 'infoSensorDescriptionService'
infoStandingOrderService = 'infoStandingOrderService'
metadataGeographicAnnotationService = 'metadataGeographicAnnotationService'
metadataProcessingService = 'metadataProcessingService'
metadataStatisticalCalculationService = 'metadataStatisticalCalculationService'
spatialCoordinateConversionService = 'spatialCoordinateConversionService'
spatialCoordinateTransformationService = 'spatialCoordinateTransformationService'
spatialCoverageVectorConversionService = 'spatialCoverageVectorConversionService'
spatialDimensionMeasurementService = 'spatialDimensionMeasurementService'
spatialFeatureGeneralizationService = 'spatialFeatureGeneralizationService'
spatialFeatureManipulationService = 'spatialFeatureManipulationService'
spatialFeatureMatchingService = 'spatialFeatureMatchingService'
spatialImageCoordinateConversionService = 'spatialImageCoordinateConversionService'
spatialImageGeometryModelConversionService = 'spatialImageGeometryModelConversionService'
spatialOrthorectificationService = 'spatialOrthorectificationService'
spatialPositioningService = 'spatialPositioningService'
spatialProcessingService = 'spatialProcessingService'
spatialProximityAnalysisService = 'spatialProximityAnalysisService'
spatialRectificationService = 'spatialRectificationService'
spatialRouteDeterminationService = 'spatialRouteDeterminationService'
spatialSamplingService = 'spatialSamplingService'
spatialSensorGeometryModelAdjustmentService = 'spatialSensorGeometryModelAdjustmentService'
spatialSubsettingService = 'spatialSubsettingService'
spatialTilingChangeService = 'spatialTilingChangeService'
subscriptionService = 'subscriptionService'
taskManagementService = 'taskManagementService'
temporalProcessingService = 'temporalProcessingService'
temporalProximityAnalysisService = 'temporalProximityAnalysisService'
temporalReferenceSystemTransformationService = 'temporalReferenceSystemTransformationService'
temporalSamplingService = 'temporalSamplingService'
temporalSubsettingService = 'temporalSubsettingService'
thematicChangeDetectionService = 'thematicChangeDetectionService'
thematicClassificationService = 'thematicClassificationService'
thematicFeatureGeneralizationService = 'thematicFeatureGeneralizationService'
thematicGeocodingService = 'thematicGeocodingService'
thematicGeographicInformationExtractionService = 'thematicGeographicInformationExtractionService'
thematicGeoparsingService = 'thematicGeoparsingService'
thematicGoparameterCalculationService = 'thematicGoparameterCalculationService'
thematicImageManipulationService = 'thematicImageManipulationService'
thematicImageProcessingService = 'thematicImageProcessingService'
thematicImageSynthesisService = 'thematicImageSynthesisService'
thematicImageUnderstandingService = 'thematicImageUnderstandingService'
thematicMultibandImageManipulationService = 'thematicMultibandImageManipulationService'
thematicObjectDetectionService = 'thematicObjectDetectionService'
thematicProcessingService = 'thematicProcessingService'
thematicReducedResolutionGenerationService = 'thematicReducedResolutionGenerationService'
thematicSpatialCountingService = 'thematicSpatialCountingService'
thematicSubsettingService = 'thematicSubsettingService'
workflowEnactmentService = 'workflowEnactmentService'
#:export
[docs]class MetaIsoScope(t.Enum):
"""ISO-19139 MD/MX_ScopeCode, see https://standards.iso.org/iso/19139/resources/gmxCodelists.xml"""
attribute = 'attribute' #: information applies to the attribute class
attributeType = 'attributeType' #: information applies to the characteristic of a feature
collectionHardware = 'collectionHardware' #: information applies to the collection hardware class
collectionSession = 'collectionSession' #: information applies to the collection session
dataset = 'dataset' #: information applies to the dataset
series = 'series' #: information applies to the series
nonGeographicDataset = 'nonGeographicDataset' #: information applies to non-geographic data
dimensionGroup = 'dimensionGroup' #: information applies to a dimension group
feature = 'feature' #: information applies to a feature
featureType = 'featureType' #: information applies to a feature type
propertyType = 'propertyType' #: information applies to a property type
fieldSession = 'fieldSession' #: information applies to a field session
software = 'software' #: information applies to a computer program or routine
service = 'service' #: information applies to a capability which a service provider entity makes available to a service user entity through a set of interfaces that define a behaviour, such as a use case
model = 'model' #: information applies to a copy or imitation of an existing or hypothetical object
tile = 'tile' #: information applies to a tile, a spatial subset of geographic data
initiative = 'initiative' #: The referencing entity applies to a transfer aggregate which was originally identified as an initiative (DS_Initiative)
stereomate = 'stereomate' #: The referencing entity applies to a transfer aggregate which was originally identified as a stereo mate (DS_StereoMate)
sensor = 'sensor' #: The referencing entity applies to a transfer aggregate which was originally identified as a sensor (DS_Sensor)
platformSeries = 'platformSeries' #: The referencing entity applies to a transfer aggregate which was originally identified as a platform series (DS_PlatformSeries)
sensorSeries = 'sensorSeries' #: The referencing entity applies to a transfer aggregate which was originally identified as a sensor series (DS_SensorSeries)
productionSeries = 'productionSeries' #: The referencing entity applies to a transfer aggregate which was originally identified as a production series (DS_ProductionSeries)
transferAggregate = 'transferAggregate' #: The referencing entity applies to a transfer aggregate which has no existence outside of the transfer context
otherAggregate = 'otherAggregate' #: The referencing entity applies to a transfer aggregate which has an existence outside of the transfer context, but which does not pertains to a specific aggregate type
#:export
[docs]class MetaIsoMaintenanceFrequencyCode(t.Enum):
"""ISO-19139 MD_MaintenanceFrequencyCode, see https://standards.iso.org/iso/19139/resources/gmxCodelists.xml"""
continual = 'continual'
daily = 'daily'
weekly = 'weekly'
fortnightly = 'fortnightly'
monthly = 'monthly'
quarterly = 'quarterly'
biannually = 'biannually'
annually = 'annually'
asNeeded = 'asNeeded'
irregular = 'irregular'
notPlanned = 'notPlanned'
unknown = 'unknown'
#:export
[docs]class MetaIsoSpatialRepresentationType(t.Enum):
"""ISO-19139 MD_SpatialRepresentationTypeCode, see https://standards.iso.org/iso/19139/resources/gmxCodelists.xml"""
vector = 'vector' #: vector data is used to represent geographic data
grid = 'grid' #: grid data is used to represent geographic data
textTable = 'textTable' #: textual or tabular data is used to represent geographic data
tin = 'tin' #: triangulated irregular network
stereoModel = 'stereoModel' #: three-dimensional view formed by the intersecting homologous rays of an overlapping pair of images
video = 'video' #: scene from a video recording
#:export
[docs]class MetaIsoOnLineFunction(t.Enum):
"""ISO-19139 CI_OnLineFunctionCode, see https://standards.iso.org/iso/19139/resources/gmxCodelists.xml"""
download = 'download' #: online instructions for transferring data from one storage device or system to another
information = 'information' #: online information about the resource
offlineAccess = 'offlineAccess' #: online instructions for requesting the resource from the provider
order = 'order' #: online order process for obtening the resource
search = 'search' #: online search interface for seeking out information about the resource
#:export
[docs]class MetaIsoTopicCategory(t.Enum):
"""ISO-19139 MD_TopicCategoryCode, see https://standards.iso.org/iso/19139/resources/gmxCodelists.xml"""
farming = 'farming' #: rearing of animals and/or cultivation of plants. Examples: agriculture, irrigation, aquaculture, plantations, herding, pests and diseases affecting crops and livestock
biota = 'biota' #: flora and/or fauna in natural environment. Examples: wildlife, vegetation, biological sciences, ecology, wilderness, sealife, wetlands, habitat
boundaries = 'boundaries' #: legal land descriptions. Examples: political and administrative boundaries
climatologyMeteorologyAtmosphere = 'climatologyMeteorologyAtmosphere' #: processes and phenomena of the atmosphere. Examples: cloud cover, weather, climate, atmospheric conditions, climate change, precipitation
economy = 'economy' #: economic activities, conditions and employment. Examples: production, labour, revenue, commerce, industry, tourism and ecotourism, forestry, fisheries, commercial or subsistence hunting, exploration and exploitation of resources such as minerals, oil and gas
elevation = 'elevation' #: height above or below sea level. Examples: altitude, bathymetry, digital elevation models, slope, derived products
environment = 'environment' #: environmental resources, protection and conservation. Examples: environmental pollution, waste storage and treatment, environmental impact assessment, monitoring environmental risk, nature reserves, landscape
geoscientificInformation = 'geoscientificInformation' #: information pertaining to earth sciences. Examples: geophysical features and processes, geology, minerals, sciences dealing with the composition, structure and origin of the earth s rocks, risks of earthquakes, volcanic activity, landslides, gravity information, soils, permafrost, hydrogeology, erosion
health = 'health' #: health, health services, human ecology, and safety. Examples: disease and illness, factors affecting health, hygiene, substance abuse, mental and physical health, health services
imageryBaseMapsEarthCover = 'imageryBaseMapsEarthCover' #: base maps. Examples: land cover, topographic maps, imagery, unclassified images, annotations
intelligenceMilitary = 'intelligenceMilitary' #: military bases, structures, activities. Examples: barracks, training grounds, military transportation, information collection
inlandWaters = 'inlandWaters' #: inland water features, drainage systems and their characteristics. Examples: rivers and glaciers, salt lakes, water utilization plans, dams, currents, floods, water quality, hydrographic charts
location = 'location' #: positional information and services. Examples: addresses, geodetic networks, control points, postal zones and services, place names
oceans = 'oceans' #: features and characteristics of salt water bodies (excluding inland waters). Examples: tides, tidal waves, coastal information, reefs
planningCadastre = 'planningCadastre' #: information used for appropriate actions for future use of the land. Examples: land use maps, zoning maps, cadastral surveys, land ownership
society = 'society' #: characteristics of society and cultures. Examples: settlements, anthropology, archaeology, education, traditional beliefs, manners and customs, demographic data, recreational areas and activities, social impact assessments, crime and justice, census information
structure = 'structure' #: man-made construction. Examples: buildings, museums, churches, factories, housing, monuments, shops, towers
transportation = 'transportation' #: means and aids for conveying persons and/or goods. Examples: roads, airports/airstrips, shipping routes, tunnels, nautical charts, vehicle or vessel location, aeronautical charts, railways
utilitiesCommunication = 'utilitiesCommunication' #: energy, water and waste systems and communications infrastructure and services. Examples: hydroelectricity, geothermal, solar and nuclear sources of energy, water purification and distribution, sewage collection and disposal, electricity and gas distribution, data communication, telecommunication, radio, communication networks
[docs]class ContactConfig(t.Config):
"""Contact metadata configuration"""
address: t.Optional[str]
area: t.Optional[str]
city: t.Optional[str]
country: t.Optional[str]
email: t.Optional[str]
fax: t.Optional[str]
organization: t.Optional[str]
person: t.Optional[str]
phone: t.Optional[str]
position: t.Optional[str]
zip: t.Optional[str]
url: t.Url = ''
[docs]class LinkConfig(t.Config):
"""Object link configuration"""
scheme: t.Optional[str] #: link scheme
url: t.Url #: link url
function: t.Optional[MetaIsoOnLineFunction] #: ISO-19115 function
[docs]class Config(t.Config):
"""Object metadata configuration"""
abstract: t.Optional[str] #: object abstract description
accessConstraints: t.Optional[str]
attribution: t.Optional[str] #: attribution (copyright) string
contact: t.Optional[ContactConfig] #: contact information
dateCreated: t.Optional[t.Date] #: publication date
dateUpdated: t.Optional[t.Date] #: modification date
fees: t.Optional[str]
image: t.Optional[t.Url] #: image (logo) url
authorityName: t.Optional[str]
authorityUrl: t.Optional[t.Url]
authorityIdentifier: t.Optional[str]
insipreKeywords: t.Optional[t.List[MetaInspireMandatoryKeyword]]
insipreMandatoryKeyword: t.Optional[MetaInspireMandatoryKeyword]
inspireDegreeOfConformity: t.Optional[MetaInspireDegreeOfConformity]
inspireResourceType: t.Optional[MetaInspireResourceType]
inspireSpatialDataServiceType: t.Optional[MetaInspireSpatialDataServiceType]
inspireTheme: t.Optional[MetaInspireTheme]
isoMaintenanceFrequencyCode: t.Optional[MetaIsoMaintenanceFrequencyCode]
isoScope: t.Optional[MetaIsoScope] #: ISO-19139 scope
isoSpatialRepresentationType: t.Optional[MetaIsoSpatialRepresentationType] #: ISO-19139 spatial type
isoTopicCategory: t.Optional[MetaIsoTopicCategory] #: ISO-19139 topic category
isoQualityConformanceExplanation: t.Optional[str]
isoQualityConformancePass: bool = False
isoQualityLineageSource: t.Optional[str]
isoQualityLineageSourceScale: t.Optional[int]
isoQualityLineageStatement: t.Optional[str]
catalogUid: t.Optional[str] #: catalog identifier
keywords: t.List[str] = [] #: keywords
language: t.Optional[str] #: object language
links: t.List[LinkConfig] = [] #: additional links
name: t.Optional[str] #: object internal name
serviceUrl: t.Optional[t.Url] #: service url
title: t.Optional[str] #: object title
url: t.Optional[t.Url] #: metadata url
urlType: t.Optional[str] #: metadata url type like "ISO19115:2003"
#:export
[docs]class MetaContact(t.Data):
address: str
area: str
city: str
country: str
email: str
fax: str
organization: str
person: str
phone: str
position: str
role: str
zip: str
url: str
#:export
#:export
[docs]class MetaData(t.Data):
abstract: str
accessConstraints: str
attribution: str
contact: MetaContact
dateCreated: t.DateTime
dateUpdated: t.DateTime
fees: str
image: t.Url
authorityName: str
authorityUrl: t.Url
authorityIdentifier: str
insipreKeywords: t.List[MetaInspireMandatoryKeyword]
insipreMandatoryKeyword: MetaInspireMandatoryKeyword
inspireDegreeOfConformity: MetaInspireDegreeOfConformity
inspireResourceType: MetaInspireResourceType
inspireSpatialDataServiceType: MetaInspireSpatialDataServiceType
inspireTheme: MetaInspireTheme
inspireThemeName: str
inspireThemeNameEn: str
isoMaintenanceFrequencyCode: MetaIsoMaintenanceFrequencyCode
isoScope: MetaIsoScope
isoSpatialRepresentationType: MetaIsoSpatialRepresentationType
isoTopicCategory: MetaIsoTopicCategory
isoQualityConformanceExplanation: str
isoQualityConformancePass: bool
isoQualityLineageSource: str
isoQualityLineageSourceScale: int
isoQualityLineageStatement: str
catalogUid: str
keywords: t.List[str]
language: str
links: t.List[MetaLink]
name: str
serviceUrl: t.Url
title: str
url: t.Url
urlType: str
[docs]class Props(t.Props):
abstract: str
attribution: str
dateCreated: str
dateUpdated: str
keywords: t.List[str]
language: str
title: str
[docs]def props(m: t.MetaData) -> Props:
return Props(
abstract=m.abstract or '',
attribution=m.attribution or '',
dateCreated=m.dateCreated,
dateUpdated=m.dateUpdated,
keywords=m.keywords or '',
language=m.language or '',
title=m.title or '',
)
[docs]def from_config(m: t.Config) -> t.MetaData:
if not m:
return t.MetaData()
meta = t.MetaData(m)
if meta.language:
meta.language3 = gws.tools.country.bibliographic_name(language=meta.language)
meta.contact = MetaContact(meta.contact or {})
if meta.keywords:
meta.keywords = gws.strip(meta.keywords) or None
if meta.inspireTheme:
meta.inspireThemeName = inspire.theme_name(meta.inspireTheme, meta.language)
meta.inspireThemeNameEn = inspire.theme_name(meta.inspireTheme, 'en')
return meta
[docs]def from_dict(d: dict) -> t.MetaData:
m = {}
contact = None
for k, v in d.items():
if k.startswith('contact.'):
contact = contact or {}
contact[k.split('.')[1]] = v
else:
m[k] = v
cfg = t.Config(m)
if contact:
cfg.contact = t.Config(contact)
return from_config(cfg)
[docs]def extend(a: t.MetaData, b: t.MetaData):
a = gws.extend(a, b)
if gws.has(b, 'contact'):
a.contact = gws.extend(a.contact, b.contact)
kwa = gws.get(a, 'keywords') or []
kwb = gws.get(b, 'keywords') or []
a.keywords = sorted(set(kwa + kwb))
return a