Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WV-3351 Integrate and validate the use of UMM-Vis to test in Worldview #5549

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/default/common/features.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"googleTagManager": true,
"vismetadata": {
"url": "https://gibs.earthdata.nasa.gov/layer-metadata/v1.0/",
"cmrVisualizationsUrl": "https://cmr.uat.earthdata.nasa.gov/search/visualizations",
"daacMap": {
"ASIPS": "Atmosphere SIPS",
"GES_DISC": "GES DISC",
Expand Down
81 changes: 61 additions & 20 deletions tasks/build-options/getVisMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const path = require('path')
const yargs = require('yargs')
const console = require('console')
const axios = require('axios').default
const xml2js = require('xml2js')

const prog = path.basename(__filename)

Expand All @@ -26,6 +27,12 @@ const options = yargs
type: 'string',
description: 'layer-metadata/all.json file'
})
.option('mode', {
demandOption: true,
alias: 'mo',
type: 'string',
description: 'mode'
})
.epilog('Creates a layer-metadata file containing all layers')

const { argv } = options
Expand Down Expand Up @@ -56,7 +63,7 @@ if (fs.existsSync(layerOrderFile)) {
const outputFile = argv.layerMetadata

const metadataConfig = features.features.vismetadata
const url = metadataConfig.url
const { url, cmrVisualizationsUrl } = metadataConfig
const daacMap = metadataConfig.daacMap || {}
const layerMetadata = {}

Expand Down Expand Up @@ -104,24 +111,29 @@ const skipLayers = [
// NOTE: Only using these properties at this time
const useKeys = [
'conceptIds',
'ConceptIds',
'dataCenter',
'daynight',
'orbitTracks',
'orbitDirection',
'ongoing',
'layerPeriod',
'title',
'subtitle'
'Title',
'subtitle',
'Subtitle',
'What'
]

async function main (url) {
async function main (url, cmrVisualizationsUrl) {
layerOrder = layerOrder.layerOrder
layerOrder = layerOrder.filter(x => !skipLayers.includes(x))

console.warn(`${prog}: Fetching ${layerOrder.length} layer-metadata files`)
for (const layerId of layerOrder) {
if (!layerId.includes('_STD') && !layerId.includes('_NRT')) {
await getMetadata(layerId, url)
if (argv.mode === 'verbose') console.warn(`${prog}: Fetching metadata for ${layerId}`)
await getMetadata(layerId, url, cmrVisualizationsUrl)
}
}

Expand All @@ -138,10 +150,11 @@ async function main (url) {
}

async function getDAAC (metadata) {
if (!Array.isArray(metadata.conceptIds) || !metadata.conceptIds.length) {
const conceptIds = metadata.conceptIds || metadata.ConceptIds
if (!Array.isArray(conceptIds) || !conceptIds.length) {
return metadata
}
for (const collection of metadata.conceptIds) {
for (const collection of conceptIds) {
const origDataCenter = collection.dataCenter
const dataCenter = daacMap[origDataCenter]
if (!dataCenter) {
Expand All @@ -157,36 +170,64 @@ async function getDAAC (metadata) {
return metadata
}

async function getMetadata (layerId, baseUrl, count) {
async function getMetadata (layerId, baseUrl, ummVisUrl, count) {
if (count) console.warn(`retry #${count} for ${layerId}`)
return axios({
method: 'get',
url: `${baseUrl}${layerId}.json`,
responseType: 'json',
timeout: 10000
}).then(async (response) => {
const metadata = response.data
const searchReq = await fetch(`${ummVisUrl}?identifier=${layerId}`, { signal: AbortSignal.timeout(10000) })
const searchText = await searchReq?.text?.() || ''
const parser = new xml2js.Parser()
const searchJson = await parser.parseStringPromise(searchText)
const location = searchJson?.results?.references?.[0]?.reference?.[0]?.location?.[0]
if (location) {
const ummVisReq = await fetch(location, { signal: AbortSignal.timeout(10000) })
const metadata = await ummVisReq.json()
layerMetadata[layerId] = await getDAAC(metadata)
let metadataKeys = Object.keys(layerMetadata[layerId])
metadataKeys = metadataKeys.filter(x => !useKeys.includes(x))
for (const key of metadataKeys) {
delete layerMetadata[layerId][key]
}
}).catch((error) => {
handleException(error, layerId, url, count)
})
// Convert keys to camelCase
for (const key in layerMetadata[layerId]) {
const firstUppercaseCharacter = key.match(/^[A-Z]/g)?.[0]
if (firstUppercaseCharacter) {
const newKey = key.replace(firstUppercaseCharacter, firstUppercaseCharacter.toLowerCase())
layerMetadata[layerId][newKey] = layerMetadata[layerId][key]
delete layerMetadata[layerId][key]
}
}
if (argv.mode === 'verbose') console.warn(layerMetadata[layerId])
} else {
return axios({
method: 'get',
url: `${baseUrl}${layerId}.json`,
responseType: 'json',
timeout: 10000
}).then(async (response) => {
const metadata = response.data
layerMetadata[layerId] = await getDAAC(metadata)
let metadataKeys = Object.keys(layerMetadata[layerId])
metadataKeys = metadataKeys.filter(x => !useKeys.includes(x))
for (const key of metadataKeys) {
delete layerMetadata[layerId][key]
}
if (argv.mode === 'verbose') console.warn(layerMetadata[layerId])
}).catch((error) => {
if (argv.mode === 'verbose') console.warn(`\n ${prog} WARN: Unable to fetch ${layerId} ${error}`)
handleException(error, layerId, url, ummVisUrl, count)
})
}
}

async function handleException (error, layerId, url, count) {
async function handleException (error, layerId, url, ummVisUrl, count) {
if (!count) count = 0
count++
if (count <= 5) {
await getMetadata(layerId, url, count)
await getMetadata(layerId, url, ummVisUrl, count)
} else {
console.warn(`\n ${prog} WARN: Unable to fetch ${layerId} ${error}`)
}
}

main(url).catch((err) => {
main(url, cmrVisualizationsUrl).catch((err) => {
console.error(err.stack)
})
3 changes: 2 additions & 1 deletion web/js/components/layer/product-picker/renderSplitTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { getOrbitTrackTitle } from '../../../modules/layers/util';
*/
export default function RenderSplitLayerTitle(props) {
const { layer } = props;
const { title, subtitle } = layer;
const title = layer.title || layer.Title;
const subtitle = layer.subtitle || layer.Subtitle;
const layerIsOrbitTrack = layer.layergroup === 'Orbital Track';
const layerTitle = !layerIsOrbitTrack ? title : `${title} (${getOrbitTrackTitle(layer, false)})`;
let splitIdx;
Expand Down
4 changes: 2 additions & 2 deletions web/js/modules/layers/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,8 @@ export function getTitles(config, layerId, projId) {
tags = forProj.tags;
}
const forLayer = config.layers[layerId];
title = title || forLayer.title || `[${layerId}]`;
subtitle = subtitle || forLayer.subtitle || '';
title = title || forLayer.title || forLayer.Title || `[${layerId}]`;
subtitle = subtitle || forLayer.subtitle || forLayer.Subtitle || '';
tags = tags || forLayer.tags || '';
return {
title,
Expand Down
Loading