Skip to content

Commit

Permalink
#38 enable ISO 19110 production/publication
Browse files Browse the repository at this point in the history
  • Loading branch information
eblondel committed Nov 4, 2019
1 parent 164df41 commit 819f5c0
Show file tree
Hide file tree
Showing 7 changed files with 334 additions and 38 deletions.
9 changes: 9 additions & 0 deletions R/geoflow_action.R
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ register_actions <- function(){
featureId = list(desc = "ID of entity data features used to identify bounding polygon(s) with option 'addfeatures'", default = NA)
)
),
geoflow_action$new(
id = "geometa-create-iso-19110",
type = "Metadata production",
def = "Produce an ISO 19110/19139 metadata object",
fun = geometa_create_iso_19110,
options = list(
doi = list(desc = "Add entity DOI - if defined - as metadata identifier and online resource", default = FALSE)
)
),
geoflow_action$new(
id="ows4R-publish-iso-19139",
type = "Metadata publication",
Expand Down
196 changes: 196 additions & 0 deletions R/geoflow_action_geometa_create_iso_19110.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
geometa_create_iso_19110 <- function(entity, config, options){

ISOMetadataNamespace$GML$uri <- "http://www.opengis.net/gml/3.2"

if(!require("geometa")){
stop("This action requires the 'geometa' package")
}

#features if any
features = entity$data$features
if(is.null(features)){
warnMsg <- sprintf("No data features associated to entity '%s'. Skip feature catalogue creation", entity$identifiers[["id"]])
config$logger.warn(warnMsg)
return(FALSE)
}

#options
doi <- if(!is.null(options$doi)) options$doi else FALSE

#feature catalogue creation
#-----------------------------------------------------------------------------------------------------
fcIdentifier <- paste0(entity$identifiers[["id"]],"_dsd")
#produce feature catalogue
fc <- ISOFeatureCatalogue$new(uuid = fcIdentifier)
fc$setName(paste0(entity$title, " - Feature Catalogue"))
fc$addFieldOfApplication("Open Science")
fc$addFieldOfApplication("FAIR")
versionDate <- as.POSIXct(Sys.time())
versionNumber <- format(versionDate, "%Y%m%dT%H%M%S")
fc$setVersionNumber(versionNumber)
fc$setVersionDate(versionDate)
fc$setFunctionalLanguage(entity$language)

#add scopes
#--------------------------------------------------------------------------
#-> geoflow scope
fc$addScope(paste0("geoflow:", entity$data$uploadType))
#-> ofv (openfairviewer) scope
ofv_scope <- "ogc_filters"
if(entity$data$uploadType == "dbquery" & length(entity$data$parameters)>0){
ofv_scope <- "ogc_viewparams"
}
if(length(entity$data$dimensions)>0){
ofv_scope <- "ogc_dimensions"
}
fc$addScope(paste0("openfairviewer:", ofv_scope))

#producer
#--------------------------------------------------------------------------
main_entity <- NULL
owners <- entity$contacts[sapply(entity$contacts, function(x){x$role == "owner"})]
if(length(owners)==0) main_entity <- entity$contacts[[1]] else main_entity <- owners[[1]]
producer <- ISOResponsibleParty$new()
producer$setIndividualName(paste(main_entity$firstName, main_entity$lastName))
producer$setOrganisationName(main_entity$organizationName)
producer$setPositionName(main_entity$positionName)
producer$setRole(main_entity$role)
contact <- ISOContact$new()
phone <- ISOTelephone$new()
phone$setVoice(main_entity$voice)
phone$setFacsimile(main_entity$facsimile)
contact$setPhone(phone)
address <- ISOAddress$new()
address$setDeliveryPoint(main_entity$postalAddress)
address$setCity(main_entity$city)
address$setPostalCode(main_entity$postalCode)
address$setCountry(main_entity$country)
address$setEmail(main_entity$email)
contact$setAddress(address)
res <- ISOOnlineResource$new()
res$setLinkage(main_entity$websiteUrl)
res$setName(main_entity$websiteName)
contact$setOnlineResource(res)
producer$setContactInfo(contact)
fc$setProducer(producer)

#citation
#--------------------------------------------------------------------------
ct <- ISOCitation$new()
ct$setTitle(entity$title)
d <- ISODate$new()
d$setDate(Sys.Date())
d$setDateType("publication")
ct$addDate(d)
ct$setEdition(versionNumber)
editionDate <- if(!is.null(entity$date)) entity$date else Sys.Date()
ct$setEditionDate(editionDate)

#set metadata identifier
ct$addIdentifier(ISOMetaIdentifier$new(code = entity$identifiers[["id"]]))
#methodology to set DOI inspired by NOAA wiki
#https://geo-ide.noaa.gov/wiki/index.php?title=DOI_Minting_Procedure#Third.2C_Include_the_DOI_and_citation_text_in_the_ISO_Metadata_Record
the_doi <- entity$identifiers[["doi"]]
if(is.null(the_doi)) the_doi <- entity$identifiers[["conceptdoi_to_save"]]
if(is.null(the_doi)) the_doi <- entity$identifiers[["doi_to_save"]]
if(!is.null(the_doi) & doi){
mdIdentifier <- ISOAnchor$new(
name = paste0("doi:", the_doi),
href = paste0("http://dx.doi.org/", the_doi)
)
mdIdentifier$setAttr("xlink:title", "DOI")
mdIdentifier$setAttr("xlink:actuate", "onRequest")
ct$addIdentifier(ISOMetaIdentifier$new(code = mdIdentifier))
}
ct$addPresentationForm("mapDigital")
fc$addDefinitionSource(ct)


#add feature type / attributes
#--------------------------------------------------------------------------
layername <- if(!is.null(entity$data$layername)) entity$data$layername else entity$identifiers$id
#create featureType
ft <- ISOFeatureType$new()
ft$setTypeName(layername)
ft$setDefinition(entity$title)
ft$setCode(layername)
ft$setIsAbstract(FALSE)

add_all_attrs <- TRUE
if(length(entity$data$attributes)>0 | length(entity$data$variables)>0) add_all_attrs <- FALSE

for(featureAttrName in colnames(features)){

#create attribute
fat <- ISOFeatureAttribute$new()
#name
memberName <- featureAttrName
fat_attrs <- entity$data$attributes[unlist(entity$data$attributes) == featureAttrName]
if(length(fat_attrs)>0){
fat_attr_desc <- attr(fat_attrs[[1]], "description")
if(!is.null(fat_attr_desc)) memberName <- fat_attr_desc
}
fat_vars <- entity$data$variables[unlist(entity$data$variables) == featureAttrName]
if(length(fat_vars)>0){
fat_var_desc <- attr(fat_vars[[1]], "description")
if(!is.null(fat_var_desc)) memberName <- fat_var_desc
}
fat$setMemberName(memberName)
#type (definition) -> attribute or variable
fat_def <- "attribute" #default definition
if(featureAttrName %in% entity$data$variables) fat_def <- "variable"
fat$setDefinition(fat_def)
fat$setCardinality(lower=1,upper=1)
#code
fat$setCode(featureAttrName)

#add listed values
featureAttrValues <- features[,featureAttrName][[1]]
addValues <- TRUE
if(is(featureAttrValues, "sfc")){
addValues <- FALSE
}else{
if(!add_all_attrs & !(featureAttrName %in% entity$data$attributes)) addValues <- FALSE
if(featureAttrName %in% entity$data$variables) addValues <- FALSE
}
if(addValues){
featureAttrValues <- unique(featureAttrValues)
for(featureAttrValue in featureAttrValues){
val <- ISOListedValue$new()
if(!is(featureAttrValue, "character")) featureAttrValue <- as(featureAttrValue, "character")
val$setCode(featureAttrValue)
val$setLabel(featureAttrValue)
val$setDefinition(featureAttrValue)
fat$listedValue <- c(fat$listedValue, val)
}
}

#add type
fat_type <- switch(class(featureAttrValues)[1],
"integer" = "xsd:int",
"numeric" = "xsd:decimal",
"character" = "xsd:string",
"logical" = "xsd:boolean",
"Date" = "xsd:date",
"POSIXct" = "xsd:datetime",
"sfc_POINT" = "gml:PointPropertyType",
"sfc_MULTIPOINT" = "gml:MultiPointPropertyType",
"sfc_LINESTRING" = "gml:LineStringPropertyType",
"sfc_MULTILINESTRING" = "gml:MultiLineStringPropertyType",
"sfc_POLYGON" = "gml:PolygonPropertyType",
"sfc_MULTIPOLYGON" = "gml:MultiPolygonPropertyType"
)
fat$setValueType(fat_type)

#add feature attribute as carrierOfCharacteristic
ft$carrierOfCharacteristics <- c(ft$carrierOfCharacteristics, fat)
}
#add featureType to catalogue
fc$addFeatureType(ft)

#we save the metadata
saveRDS(fc, file.path(getwd(), "metadata", paste0(fcIdentifier, ".rds")))
fc$save(file.path(getwd(), "metadata", paste0(entity$identifiers[["id"]], "_ISO-19110.xml")))

return(fc)
}
15 changes: 14 additions & 1 deletion R/geoflow_action_geometa_create_iso_19115.R
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,20 @@ geometa_create_iso_19115 <- function(entity, config, options){
dq2$addReport(dc_inspire2)
}

#TODO content information --> Feature Catalogue description (if data handling)
#content information --> Feature Catalogue description (if data handling)
fc_action <- NULL
actions <- config$actions[sapply(config$actions, function(x){x$id=="geometa-create-iso-19110"})]
if(length(actions)>0) fc_action <- actions[[1]]
if(!is.null(fc_action)){
fcIdentifier <- paste0(entity$identifiers[["id"]],"_dsd")
config$logger.info("Adding content information (feature catalogue description) to ISO 19115")
fcd <- ISOFeatureCatalogueDescription$new()
fcd$setComplianceCode(TRUE)
fcd$addLanguage(entity$language)
fcd$setIncludedWithDataset(FALSE)
fcd$featureCatalogueCitation <- list(ISOAttributes$new(uuidref = fcIdentifier))
md$addContentInfo(fcd)
}

#we save the metadata
saveRDS(md, file.path(getwd(), "metadata", paste0(entity$identifiers[["id"]], ".rds")))
Expand Down
82 changes: 56 additions & 26 deletions R/geoflow_action_geonapi_publish_iso_19139.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,65 @@ geonapi_publish_iso_19139 <- function(entity, config, options){
stop(errMsg)
}

privileges <- if(!is.null(options$privileges)) options$privileges else c("view","dynamic","featured")

#to insert or update a metadata into a geonetwork.
#An insert has to be done in 2 operations (the insert itself, and the privilege setting to "publish" it either to a restrained group or to public)
#An update has to be done based on the internal Geonetwork id (that can be queried as well
privileges <- if(!is.null(options$privileges)) options$privileges else c("view","dynamic","featured")
metaFile <- file.path("metadata", paste0(entity$identifiers[["id"]],".rds"))
md <- readRDS(metaFile)
if(is(md, "ISOMetadata")) privileges <- privileges[privileges!="featured"]
metaId <- GN$get(entity$identifiers[["id"]], by = "uuid", output = "id")
if(is.null(metaId)){
#insert metadata (once inserted only visible to the publisher)
group <- if(!is.null(options$group)) options$group else "1"
category <- if(!is.null(options$category)) options$category else "datasets"
created = GN$insertMetadata(geometa = md, group = group, category = category,
geometa_inspire = geometa_inspire)

#config privileges
config <- GNPrivConfiguration$new()
config$setPrivileges("all", privileges)
GN$setPrivConfiguration(id = created, config = config)
}else{
#update a metadata
updated = GN$updateMetadata(id = metaId, geometa = md,
geometa_inspire = geometa_inspire)

#config privileges
gn_config <- GNPrivConfiguration$new()
gn_config$setPrivileges("all", privileges)
GN$setPrivConfiguration(id = metaId, config = gn_config)
#function doPublish
doPublish <- function(mdfile){
mdId <- NULL
md <- readRDS(metaFile)
privs <- privileges
if(is(md, "ISOMetadata")){
mdId <- md$fileIdentifier
privs <- privileges[privileges!="featured"]
}
if(is(md, "ISOFeatureCatalogue")){
mdId <- md$attrs[["uuid"]]
privs <- "view"
}
metaId <- GN$get(mdId, by = "uuid", output = "id")
if(is.null(metaId)){
#insert metadata (once inserted only visible to the publisher)
group <- if(!is.null(options$group)) options$group else "1"
category <- if(!is.null(options$category)) options$category else "datasets"
created = GN$insertMetadata(geometa = md, group = group, category = category,
geometa_inspire = geometa_inspire)

#config privileges
config <- GNPrivConfiguration$new()
config$setPrivileges("all", privs)
GN$setPrivConfiguration(id = created, config = config)
}else{
#update a metadata
updated = GN$updateMetadata(id = metaId, geometa = md,
geometa_inspire = geometa_inspire)

#config privileges
gn_config <- GNPrivConfiguration$new()
gn_config$setPrivileges("all", privs)
GN$setPrivConfiguration(id = metaId, config = gn_config)
}
}

#geometa ISO 19115
geometa_iso19115_action <- NULL
actions <- config$actions[sapply(config$actions, function(x){x$id=="geometa-create-iso-19115"})]
if(length(actions)>0) geometa_iso19115_action <- actions[[1]]
if(!is.null(geometa_iso19115_action)){
metaFile <- file.path("metadata", paste0(entity$identifiers[["id"]],".rds"))
if(file.exists(metaFile)) doPublish(metaFile)
}
#geometa ISO 19110
geometa_iso19110_action <- NULL
actions <- config$actions[sapply(config$actions, function(x){x$id=="geometa-create-iso-19110"})]
if(length(actions)>0) geometa_iso19110_action <- actions[[1]]
if(!is.null(geometa_iso19110_action)){
geometa_inspire <- FALSE
metaFile <- file.path("metadata", paste0(entity$identifiers[["id"]],"_dsd",".rds"))
if(file.exists(metaFile)) doPublish(metaFile)
}

return(metaId)
return(TRUE)
}
46 changes: 35 additions & 11 deletions R/geoflow_action_ows4R_publish_iso_19139.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ ows4R_publish_iso_19139 <- function(entity, config, options){
stop("Package 'ows4R' is required for this action")
}

metaFile <- file.path("metadata", paste0(entity$identifiers[["id"]],".rds"))
md <- readRDS(metaFile)

#shortcut for csw config
CSW <- config$software$output$csw

Expand All @@ -24,13 +21,40 @@ ows4R_publish_iso_19139 <- function(entity, config, options){
stop(errMsg)
}

meta_dc <- CSW$getRecordById(entity$identifiers[["id"]])
if(is.null(meta_dc)){
config$logger.info(sprintf("Inserting new record with id '%s'", meta_dc))
CSW$insertRecord(record = md, geometa_inspire = geometa_inspire)
}else{
config$logger.info(sprintf("Updating existing record with id '%s'", meta_dc))
CSW$updateRecord(record = md, geometa_inspire = geometa_inspire)
#function to publish
doPublish <- function(md){
meta_id <- NULL
if(is(md, "ISOMetadata")) meta_id <- md$fileIdentifier
if(is(md, "ISOFeatureCatalogue")) meta_id <- md$attrs[["uuid"]]
meta_dc <- CSW$getRecordById(meta_id)
if(is.null(meta_dc)){
config$logger.info(sprintf("Inserting new record with id '%s'", meta_dc))
CSW$insertRecord(record = md, geometa_inspire = geometa_inspire)
}else{
config$logger.info(sprintf("Updating existing record with id '%s'", meta_dc))
CSW$updateRecord(record = md, geometa_inspire = geometa_inspire)
}
}

#geometa ISO 19115
geometa_iso19115_action <- NULL
actions <- config$actions[sapply(config$actions, function(x){x$id=="geometa-create-iso-19115"})]
if(length(actions)>0) geometa_iso19115_action <- actions[[1]]
if(!is.null(geometa_iso19115_action)){
metaFile <- file.path("metadata", paste0(entity$identifiers[["id"]],".rds"))
md <- readRDS(metaFile)
if(file.exists(metaFile)) doPublish(md)
}
return(md$fileIdentifier)
#geometa ISO 19110
geometa_iso19110_action <- NULL
actions <- config$actions[sapply(config$actions, function(x){x$id=="geometa-create-iso-19110"})]
if(length(actions)>0) geometa_iso19110_action <- actions[[1]]
if(!is.null(geometa_iso19110_action)){
geometa_inspire <- FALSE
metaFile <- file.path("metadata", paste0(entity$identifiers[["id"]],"_dsd",".rds"))
md <- readRDS(metaFile)
if(file.exists(metaFile)) doPublish(md)
}

return(TRUE)
}
Loading

0 comments on commit 819f5c0

Please sign in to comment.