Select Git revision
UserInterfaceState.xcuserstate
FetchData.js 9.29 KiB
/**
*
* @returns
*/
export default async function Initialize(){
// Astro Web Maps, has the tile base data for the map of each planetary body
const astroWebMaps =
"https://astrowebmaps.wr.usgs.gov/webmapatlas/Layers/maps.json";
// STAC API, has footprint data for select planetary bodies
const stacApiCollections =
"https://stac.astrogeology.usgs.gov/api/collections";
const vectorApiCollections =
"https://astrogeology.usgs.gov/pygeoapi/collections";
// Async tracking
let fetchStatus = {};
let fetchPromise = {};
let jsonPromise = {};
// Fetched Maps
let mapsJson = {};
// Combined Data
let aggregateMapList = {};
// Init
fetchStatus[astroWebMaps] = "Not Started";
fetchPromise[astroWebMaps] = "Not Started";
jsonPromise[astroWebMaps] = "Not Started";
mapsJson[astroWebMaps] = [];
fetchStatus[stacApiCollections] = "Not Started";
fetchPromise[stacApiCollections] = "Not Started";
jsonPromise[stacApiCollections] = "Not Started";
mapsJson[stacApiCollections] = [];
fetchStatus[vectorApiCollections] = "Not Started";
fetchPromise[vectorApiCollections] = "Not Started";
jsonPromise[vectorApiCollections] = "Not Started";
mapsJson[vectorApiCollections] = [];
// Fetch JSON and read into object
async function ensureFetched(targetUrl) {
if(fetchStatus[targetUrl] === "Not Started")
{
fetchStatus[targetUrl] = "Started";
fetchPromise[targetUrl] = fetch(
targetUrl
).then((res)=>{
jsonPromise[targetUrl] = res.json().then((jsonData)=>{
mapsJson[targetUrl] = jsonData;
}).catch((err)=>{
console.log(err);
});
}).catch((err) => {
console.log(err);
});
}
await fetchPromise[targetUrl];
await jsonPromise[targetUrl];
}
// Combine data from Astro Web Maps and STAC API into one new object
function organizeData(astroWebMaps, stacApiCollections, vectorApiCollections) {
// Initialize Objects
let mapList = { "systems" : [] };
let stacList = [];
// Check for Planets that have STAC footprints from the STAC API
for (let i = 0; i < stacApiCollections.collections.length; i++) {
let stacTarget = stacApiCollections.collections[i].summaries["ssys:targets"][0].toLowerCase();
// pushes stacTarget onto the stacList if the target isn't already in the list
if(!stacList.find(targetBody => targetBody == stacTarget)){
stacList.push(stacTarget.toLowerCase());
}
}
// Scan through every target in the Astro Web Maps JSON
for (const target of astroWebMaps.targets){
// Check for, add system if system is not in array
if (!mapList.systems.some(system => system.name === target.system)) {
mapList.systems.push({
"name" : target.system,
"naif" : 0,
"bodies" : []
})
}
// Index of System
let sysIndex = mapList.systems.map(sys => sys.name).indexOf(target.system);
// ID the system. This seems to get the main planet of the system.
if (target.naif % 100 === 99){
mapList.systems[sysIndex].naif = target.naif;
}
// Check for/add body if not already incl
if (!mapList.systems[sysIndex].bodies.some(body => body.name === target.name)) {
// A flag that indicates whether or not the body has footprints
let hasFootprints = stacList.includes(target.name.toLowerCase())
// Add STAC collections
let myCollections = []
if (hasFootprints) {
for (const collection of stacApiCollections.collections){
if (target.name == collection.summaries["ssys:targets"][0].toUpperCase()) {
// Add a specification to the title in order to show what kind of data the user is requesting
collection.title = collection.title.concat(" (Raster)")
myCollections.push(collection);
}
}
for (const pycollection of vectorApiCollections.collections){
// view the collection as GEOJSON
let target_name = pycollection.id.split('/')[0];
if (target.name == target_name.toUpperCase()) {
pycollection.links.find(link => link.rel === "items").href = "https://astrogeology.usgs.gov/pygeoapi" + pycollection.links.find(link => link.rel === "items").href;
// Add a specification to the title in order to show what kind of data the user is requesting
pycollection.title = pycollection.title.concat(" (Vector)");
myCollections.push(pycollection);
}
}
}
// Add a body data entry
mapList.systems[sysIndex].bodies.push({
"name" : target.name,
"naif" : target.naif,
"hasFootprints" : hasFootprints,
"layers" : {
"base" : [],
"overlays" : [],
"nomenclature" : []
},
"collections" : myCollections
})
}
// Index of Body
let bodIndex = mapList.systems[sysIndex].bodies.map(bod => bod.name).indexOf(target.name);
// Sort through AstroWebMaps to get the right ones for GeoSTAC
function getWmsMaps(webMaps) {
let myLayers = {
"base" : [],
"overlays" : [],
"nomenclature" : [],
/* "wfs" : [] */
};
// Add maps
for (const wmap of webMaps) {
if(wmap.type === "WMS" && wmap.layer != "GENERIC") {
if(wmap.transparent == "false") {
// Non-transparent layers are base maps
myLayers.base.push(wmap);
} else if (wmap.layer == "NOMENCLATURE") {
// Feature Name Layers
myLayers.nomenclature.push(wmap);
} else {
// OthTransparent layers are overlays
myLayers.overlays.push(wmap);
}
}
// else if (wmap.type === "WFS") {
// // Currently in AstroMap but doesn't seem to be used.
// myLayers.wfs.push(wmap);
// }
}
return myLayers;
}
// Add base and overlay maps (but not empty arrays!)
let myLayers = getWmsMaps(target.webmap);
if (myLayers.base.length > 0){
mapList.systems[sysIndex].bodies[bodIndex].layers.base.push(...myLayers.base);
}
if (myLayers.nomenclature.length > 0){
mapList.systems[sysIndex].bodies[bodIndex].layers.nomenclature.push(...myLayers.nomenclature);
}
if (myLayers.overlays.length > 0){
mapList.systems[sysIndex].bodies[bodIndex].layers.overlays.push(...myLayers.overlays);
}
}
// Sort systems by NAIF ID
mapList.systems.sort((a, b)=>{return a.naif - b.naif})
// Go through each System
for (let sysIndex = 0; sysIndex < mapList.systems.length; sysIndex++){
// Remove bodies with no base maps
for (let bodIndex = mapList.systems[sysIndex].bodies.length - 1; bodIndex >= 0; bodIndex--){
if(mapList.systems[sysIndex].bodies[bodIndex].layers.base.length < 1){
mapList.systems[sysIndex].bodies.splice(bodIndex, 1);
}
}
// Sort targets by naif id
mapList.systems[sysIndex].bodies.sort((a, b)=>{
let valA = a.naif;
let valB = b.naif;
if (a.naif % 100 == 99) valA = 0; // Planet IDs end with 99,
if (b.naif % 100 == 99) valB = 0; // but put them first.
return valA - valB;
})
}
return mapList;
}
// Fetch and organize data from
async function getStacAndAstroWebMapsData() {
// Start fetching from AWM and STAC API concurrently
ensureFetched(astroWebMaps);
ensureFetched(stacApiCollections);
ensureFetched(vectorApiCollections);
// Wait for both to complete before moving on
await ensureFetched(astroWebMaps);
await ensureFetched(stacApiCollections);
await ensureFetched(vectorApiCollections);
return organizeData(mapsJson[astroWebMaps], mapsJson[stacApiCollections], mapsJson[vectorApiCollections]);
}
aggregateMapList = await getStacAndAstroWebMapsData();
return { "aggregateMapList":aggregateMapList, "astroWebMaps":mapsJson[astroWebMaps] };
}