Skip to content
Merged
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
4 changes: 2 additions & 2 deletions tasks/build-options/extractConfigFromWMTS.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ async function processEntry (entry) {
for (const gcLayer of gcContents.Layer) {
try {
layerCount += 1
processLayer(gcLayer, wvLayers, entry)
await processLayer(gcLayer, wvLayers, entry)
} catch (error) {
if (error instanceof SkipException) {
warningCount += 1
Expand Down Expand Up @@ -184,7 +184,7 @@ async function processLayer (gcLayer, wvLayers, entry) {
const dimension = gcLayer.Dimension
if (dimension['ows:Identifier']._text === 'Time') {
try {
wvLayer = await processTemporalLayer(wvLayer, dimension.Value)
wvLayer = await processTemporalLayer(wvLayer, dimension.Value, entry.source)
} catch (e) {
console.error(e)
console.error(`${prog}: ERROR: [${ident}] Error processing time values.`)
Expand Down
161 changes: 95 additions & 66 deletions tasks/build-options/processTemporalLayer.js
Original file line number Diff line number Diff line change
@@ -1,88 +1,117 @@
const moment = require('moment')
const xml2js = require('xml2js')

const projDict = {
'GIBS:geographic': 'epsg4326',
'GIBS:arctic': 'epsg3413',
'GIBS:antarctic': 'epsg3031'
}

function toList (val) {
return val instanceof Array ? val : [val]
}

async function processTemporalLayer (wvLayer, value) {
async function processTemporalLayer (wvLayer, value, source = 'GIBS:geographic') {
const dateFormat = 'YYYY-MM-DD'
const dateTimeFormat = 'YYYY-MM-DD HH:mm:ss'
try {
const ranges = toList(value)
if (ranges && ranges[0] && ranges[0]._text && ranges[0]._text.includes('T')) {
wvLayer.period = 'subdaily'
} else {
if (ranges && ranges[0] && ranges[0]._text && ranges[0]._text.endsWith('Y')) {
wvLayer.period = 'yearly'
} else if (ranges && ranges[0] && ranges[0]._text && ranges[0]._text.endsWith('M')) {
wvLayer.period = 'monthly'
} else {
wvLayer.period = 'daily'
}
}
let startDate = moment.min()
let endDate = moment.max()
const dateRangeStart = []
const dateRangeEnd = []
const rangeInterval = []
for (const range of ranges) {
const [start, end, interval] = range._text.split('/')
if (
wvLayer.period === 'daily' ||
wvLayer.period === 'monthly' ||
wvLayer.period === 'yearly'
) {
startDate = moment.min(startDate, moment(start, dateFormat))
endDate = moment.max(endDate, moment(end, dateFormat))
if (start) {
startDate = moment(start, dateFormat).format('YYYY-MM-DDTHH:mm:ss[Z]')
dateRangeStart.push(startDate)
}
if (end) {
endDate = moment(end, dateFormat).format('YYYY-MM-DDTHH:mm:ss[Z]')
let ranges = toList(value)
const describeDomainsUrl = `https://gibs.earthdata.nasa.gov/wmts/${projDict[source]}/best/1.0.0/${wvLayer.id}/default/250m/all/all.xml`
try {
const describeDomainsResponse = await fetch(describeDomainsUrl)
if (describeDomainsResponse?.ok) {
const describeDomainsText = await describeDomainsResponse?.text?.() || ''
const parser = new xml2js.Parser()
const describeDomainsJson = await parser.parseStringPromise(describeDomainsText)
const domain = describeDomainsJson?.Domains?.DimensionDomain?.[0]?.Domain?.[0] || ''
const domains = domain.split(',')
if (domains?.length) {
const formattedDomains = domains.map((d) => {
return {
_text: d
}
})
ranges = toList(formattedDomains)
}
if (interval !== 'P1D') {
endDate = moment.utc(endDate).add(moment.duration(interval)).format('YYYY-MM-DDTHH:mm:ss[Z]')
// For monthly products subtract 1 day
if (wvLayer.period === 'monthly') {
endDate = moment.utc(endDate).subtract(1, 'day').format('YYYY-MM-DDTHH:mm:ss[Z]')
}
}
const regex = /\d+/g
const match = regex.exec(interval)
rangeInterval.push(match)
if (endDate.endsWith('T00:00:00Z')) {
endDate = endDate.replace('T00:00:00Z', 'T23:59:59Z')
}
dateRangeEnd.push(endDate)
}
} catch (error) {
console.error(`Error fetching ${describeDomainsUrl}: ${error}`)
} finally {
if (ranges && ranges[0] && ranges[0]._text && ranges[0]._text.includes('T')) {
wvLayer.period = 'subdaily'
} else {
// Subdaily Layers
startDate = moment(start, dateTimeFormat).format('YYYY-MM-DDTHH:mm:ss[Z]')
endDate = moment(end, dateTimeFormat).format('YYYY-MM-DDTHH:mm:ss[Z]')

if (start) {
dateRangeStart.push(startDate)
if (ranges && ranges[0] && ranges[0]._text && ranges[0]._text.endsWith('Y')) {
wvLayer.period = 'yearly'
} else if (ranges && ranges[0] && ranges[0]._text && ranges[0]._text.endsWith('M')) {
wvLayer.period = 'monthly'
} else {
wvLayer.period = 'daily'
}
if (end) {
}
let startDate = moment.min()
let endDate = moment.max()
const dateRangeStart = []
const dateRangeEnd = []
const rangeInterval = []
for (const range of ranges) {
const [start, end, interval] = range._text.split('/')
if (
wvLayer.period === 'daily' ||
wvLayer.period === 'monthly' ||
wvLayer.period === 'yearly'
) {
startDate = moment.min(startDate, moment(start, dateFormat))
endDate = moment.max(endDate, moment(end, dateFormat))
if (start) {
startDate = moment(start, dateFormat).format('YYYY-MM-DDTHH:mm:ss[Z]')
dateRangeStart.push(startDate)
}
if (end) {
endDate = moment(end, dateFormat).format('YYYY-MM-DDTHH:mm:ss[Z]')
}
if (interval !== 'P1D') {
endDate = moment.utc(endDate).add(moment.duration(interval)).format('YYYY-MM-DDTHH:mm:ss[Z]')
// For monthly products subtract 1 day
if (wvLayer.period === 'monthly') {
endDate = moment.utc(endDate).subtract(1, 'day').format('YYYY-MM-DDTHH:mm:ss[Z]')
}
}
const regex = /\d+/g
const match = regex.exec(interval)
rangeInterval.push(match)
if (endDate.endsWith('T00:00:00Z')) {
endDate = endDate.replace('T00:00:00Z', 'T23:59:59Z')
}
dateRangeEnd.push(endDate)
}
} else {
// Subdaily Layers
startDate = moment(start, dateTimeFormat).format('YYYY-MM-DDTHH:mm:ss[Z]')
endDate = moment(end, dateTimeFormat).format('YYYY-MM-DDTHH:mm:ss[Z]')

rangeInterval.push(interval.match(/\d+/)[0])
}
if (start) {
dateRangeStart.push(startDate)
}
if (end) {
dateRangeEnd.push(endDate)
}

wvLayer.startDate = dateRangeStart[0]
wvLayer.endDate = dateRangeEnd[dateRangeEnd.length - 1]
rangeInterval.push(interval.match(/\d+/)[0])
}

if (dateRangeStart.length && dateRangeEnd.length) {
wvLayer.dateRanges = dateRangeStart.map((s, i) => ({
startDate: s,
endDate: dateRangeEnd[i],
dateInterval: rangeInterval[i]
}))
wvLayer.startDate = dateRangeStart[0]
wvLayer.endDate = dateRangeEnd[dateRangeEnd.length - 1]

if (dateRangeStart.length && dateRangeEnd.length) {
wvLayer.dateRanges = dateRangeStart.map((s, i) => ({
startDate: s,
endDate: dateRangeEnd[i],
dateInterval: rangeInterval[i]
}))
}
}
}
} catch (e) {
throw new Error(`Error processing temporal layer: ${e}`)
throw new Error(`Error processing temporal layer ${wvLayer.id}: ${e}`)
}
return wvLayer
}
Expand Down
3 changes: 2 additions & 1 deletion web/js/components/layer/info/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default function LayerInfo ({ layer, measurementDescriptionPath }) {
id,
period,
startDate,
ongoing,
} = layer;

const [layerMetadata, setLayerMetadata] = useState();
Expand Down Expand Up @@ -47,7 +48,7 @@ export default function LayerInfo ({ layer, measurementDescriptionPath }) {
const overlapDateRanges = hasLayerDateRange
? dateOverlap(period, dateRanges)
: [];
return hasLayerDateRange && overlapDateRanges.overlap === false;
return hasLayerDateRange && overlapDateRanges.overlap === false && !ongoing;
};

const needDateRanges = getDateOverlapDateRanges();
Expand Down