Loading .gitignore +3 −0 Original line number Diff line number Diff line Loading @@ -18,3 +18,6 @@ app/node_modules .Trashes ehthumbs.db Thumbs.db # IDE generated files .vscode No newline at end of file src/components/presentational/FootprintResults.jsx +1 −5 Original line number Diff line number Diff line Loading @@ -61,12 +61,8 @@ export default function FootprintResults(props) { setCollectionId(newCollectionId); setMatched(featureCollections[newCollectionId].numberMatched); // Extract the selected collection title const selectedCollection = props.target.collections.find(collection => collection.id === newCollectionId); const selectedCollectionTitle = selectedCollection ? selectedCollection.title : ''; // Call the callback function to pass the selected title to the Sidebar props.updateSelectedTitle(selectedCollectionTitle); props.updateAvailableQueriables(props.target.collections.find(col => col.id === newCollectionId).querTitles); props.UpdateQueryableTitles(null); Loading src/components/presentational/SearchAndFilterInput.jsx +31 −77 Original line number Diff line number Diff line Loading @@ -147,9 +147,6 @@ export default function SearchAndFilterInput(props) { props.setFilterString(myFilterString); } // initialize pyGeoAPI flag let pyGeoAPIFlag = false; // New state for queryable titles const [queryableTitles, setQueryableTitles] = useState([]); Loading @@ -160,57 +157,11 @@ export default function SearchAndFilterInput(props) { const isInPyAPI = collection.filter(data => data.hasOwnProperty('itemType')); // finds and assigns the selected collection from the PYGEO api const selectedCollection = isInPyAPI.find(data => data.title === props.selectedTitle); const selectedCollection = isInPyAPI.find(data => data.title === props.availableQueriables); // retrieves all pyGEO titles const collectionTitles = isInPyAPI.map(data => data.title); // checks if correct title selected if (collectionTitles.includes(props.selectedTitle)) { //set pyGeoAPI flag pyGeoAPIFlag = true; // set the selected link let QueryableDirectoryLink = selectedCollection.links.find(link => link.rel === "queryables").href; // creates URL to get the properties let QueryableURL = 'https://astrogeology.usgs.gov/pygeoapi/' + QueryableDirectoryLink; // fetches URL to get the properties fetch(QueryableURL) .then(response => response.json()) .then(data => { let queryableTitlesArray = []; // Extract the "properties" property from the JSON response let Queryables = data.properties; // loop over titles for (const property in Queryables) { if (Queryables.hasOwnProperty(property) && Queryables[property].hasOwnProperty("title")) { queryableTitlesArray.push(data.properties[property].title); } } // Set the state with the queryable titles setQueryableTitles(queryableTitlesArray); }, []) .catch(error => { console.error("Error fetching data:", error); }); } const [selectedOptions, setSelectedOptions] = useState([]); const handleOptionChange = event => { Loading Loading @@ -326,7 +277,7 @@ export default function SearchAndFilterInput(props) { <Collapse in={expandFilter}> <div className="panelSection panelBar"> <span> <FormControl sx={{ minWidth: 150 }}> <FormControl sx={{ minWidth: 180 }}> <InputLabel id="sortByLabel" size="small"> Sort By </InputLabel> Loading Loading @@ -357,23 +308,25 @@ export default function SearchAndFilterInput(props) { </span> </div> {pyGeoAPIFlag && ( {props.availableQueriables.length > 0 && ( <> <Divider/> <div className="panelSection panelBar"> <span> <FormControl sx={{ minWidth: 150 , minHeight: 40}}> <InputLabel id="selectQueryLabel" size="small" style={{paddingTop: '0.2rem'}}> <FormControl sx={{ minWidth: 180 , minHeight: 40}}> <InputLabel id="showPropertiesLabel" size="small" style={{paddingTop: '0.2rem'}}> Show Properties </InputLabel> <Select labelId="selectQueryLabel" label="Select Query" labelId="showPropertiesLabel" label="Show Properties" multiple value={selectedOptions} onChange={handleOptionChange} renderValue={(selected) => selected.join(', ')} style={{height: 43}} > {queryableTitles.map((title) => ( {props.availableQueriables.map((title) => ( <MenuItem key={title} value={title}> <Checkbox checked={selectedOptions.includes(title)} /> <ListItemText primary={title} /> Loading @@ -383,6 +336,7 @@ export default function SearchAndFilterInput(props) { </FormControl> </span> </div> </> )} <Divider/> Loading src/components/presentational/Sidebar.jsx +6 −5 Original line number Diff line number Diff line Loading @@ -44,11 +44,12 @@ export default function Sidebar(props) { }; // State to hold the selected title const [selectedTitle, setSelectedTitle] = React.useState(""); const [availableQueriables, setAvailableQueriables] = React.useState(""); // Callback function to update selected title const updateSelectedTitle = (newTitle) => { setSelectedTitle(newTitle); const updateAvailableQueriables = (queriables) => { console.log(queriables); setAvailableQueriables(queriables); }; // State to hold the seleced queryables Loading @@ -72,7 +73,7 @@ export default function Sidebar(props) { setFilterString={setFilterString} targetName={props.target.name} target={props.target} selectedTitle={selectedTitle} availableQueriables={availableQueriables} UpdateQueryableTitles = {UpdateQueryableTitles} /> <FootprintResults Loading @@ -80,7 +81,7 @@ export default function Sidebar(props) { filterString={filterString} queryAddress={props.queryAddress} setQueryAddress={props.setQueryAddress} updateSelectedTitle={updateSelectedTitle} updateAvailableQueriables={updateAvailableQueriables} selectedQueryables = {updatedQueryableTitles} UpdateQueryableTitles = {UpdateQueryableTitles} /> Loading src/js/FetchData.js +34 −3 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ export default async function Initialize(){ } // Combine data from Astro Web Maps and STAC API into one new object function organizeData(astroWebMaps, stacApiCollections, vectorApiCollections) { async function organizeData(astroWebMaps, stacApiCollections, vectorApiCollections) { // Initialize Objects let mapList = { "systems" : [] }; Loading Loading @@ -97,6 +97,8 @@ export default async function Initialize(){ let sysIndex = mapList.systems.map(sys => sys.name).indexOf(target.system); // ID the system. This seems to get the main planet of the system. // https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html // "A planet is always considered to be the 99th satellite of its own barycenter" if (target.naif % 100 === 99){ mapList.systems[sysIndex].naif = target.naif; } Loading @@ -113,7 +115,9 @@ export default async function Initialize(){ 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)") collection.dataType = "raster"; collection.querTitles = []; collection.title = collection.title.concat(" (Raster)"); myCollections.push(collection); } } Loading @@ -122,8 +126,33 @@ export default async function Initialize(){ // view the collection as GEOJSON let target_name = pycollection.id.split('/')[0]; if (target.name == target_name.toUpperCase()) { // Set links GeoSTAC needs later pycollection.links.find(link => link.rel === "items").href = "https://astrogeology.usgs.gov/pygeoapi" + pycollection.links.find(link => link.rel === "items").href; pycollection.itemsLink = "https://astrogeology.usgs.gov/pygeoapi" + pycollection.links.find(link => link.rel === "items").href; pycollection.queryablesLink = "https://astrogeology.usgs.gov/pygeoapi" + pycollection.links.find(link => link.rel === "queryables").href; // Fetch and await queriables fetchStatus[pycollection.queryablesLink] = "Not Started"; fetchPromise[pycollection.queryablesLink] = "Not Started"; jsonPromise[pycollection.queryablesLink] = "Not Started"; mapsJson[pycollection.queryablesLink] = []; ensureFetched(pycollection.queryablesLink); await ensureFetched(pycollection.queryablesLink); // put queryable titles in array let querData = mapsJson[pycollection.queryablesLink]; let querTitles = []; let querProps = querData.properties; for (const property in querProps) { if (querProps.hasOwnProperty(property) && querProps[property].hasOwnProperty("title")) { querTitles.push(querData.properties[property].title); } } // Add a specification to the title in order to show what kind of data the user is requesting pycollection.dataType = "vector"; pycollection.querTitles = querTitles; pycollection.title = pycollection.title.concat(" (Vector)"); myCollections.push(pycollection); } Loading Loading @@ -228,7 +257,9 @@ export default async function Initialize(){ await ensureFetched(stacApiCollections); await ensureFetched(vectorApiCollections); return organizeData(mapsJson[astroWebMaps], mapsJson[stacApiCollections], mapsJson[vectorApiCollections]); let organizedData = await organizeData(mapsJson[astroWebMaps], mapsJson[stacApiCollections], mapsJson[vectorApiCollections]); return organizedData; } aggregateMapList = await getStacAndAstroWebMapsData(); Loading Loading
.gitignore +3 −0 Original line number Diff line number Diff line Loading @@ -18,3 +18,6 @@ app/node_modules .Trashes ehthumbs.db Thumbs.db # IDE generated files .vscode No newline at end of file
src/components/presentational/FootprintResults.jsx +1 −5 Original line number Diff line number Diff line Loading @@ -61,12 +61,8 @@ export default function FootprintResults(props) { setCollectionId(newCollectionId); setMatched(featureCollections[newCollectionId].numberMatched); // Extract the selected collection title const selectedCollection = props.target.collections.find(collection => collection.id === newCollectionId); const selectedCollectionTitle = selectedCollection ? selectedCollection.title : ''; // Call the callback function to pass the selected title to the Sidebar props.updateSelectedTitle(selectedCollectionTitle); props.updateAvailableQueriables(props.target.collections.find(col => col.id === newCollectionId).querTitles); props.UpdateQueryableTitles(null); Loading
src/components/presentational/SearchAndFilterInput.jsx +31 −77 Original line number Diff line number Diff line Loading @@ -147,9 +147,6 @@ export default function SearchAndFilterInput(props) { props.setFilterString(myFilterString); } // initialize pyGeoAPI flag let pyGeoAPIFlag = false; // New state for queryable titles const [queryableTitles, setQueryableTitles] = useState([]); Loading @@ -160,57 +157,11 @@ export default function SearchAndFilterInput(props) { const isInPyAPI = collection.filter(data => data.hasOwnProperty('itemType')); // finds and assigns the selected collection from the PYGEO api const selectedCollection = isInPyAPI.find(data => data.title === props.selectedTitle); const selectedCollection = isInPyAPI.find(data => data.title === props.availableQueriables); // retrieves all pyGEO titles const collectionTitles = isInPyAPI.map(data => data.title); // checks if correct title selected if (collectionTitles.includes(props.selectedTitle)) { //set pyGeoAPI flag pyGeoAPIFlag = true; // set the selected link let QueryableDirectoryLink = selectedCollection.links.find(link => link.rel === "queryables").href; // creates URL to get the properties let QueryableURL = 'https://astrogeology.usgs.gov/pygeoapi/' + QueryableDirectoryLink; // fetches URL to get the properties fetch(QueryableURL) .then(response => response.json()) .then(data => { let queryableTitlesArray = []; // Extract the "properties" property from the JSON response let Queryables = data.properties; // loop over titles for (const property in Queryables) { if (Queryables.hasOwnProperty(property) && Queryables[property].hasOwnProperty("title")) { queryableTitlesArray.push(data.properties[property].title); } } // Set the state with the queryable titles setQueryableTitles(queryableTitlesArray); }, []) .catch(error => { console.error("Error fetching data:", error); }); } const [selectedOptions, setSelectedOptions] = useState([]); const handleOptionChange = event => { Loading Loading @@ -326,7 +277,7 @@ export default function SearchAndFilterInput(props) { <Collapse in={expandFilter}> <div className="panelSection panelBar"> <span> <FormControl sx={{ minWidth: 150 }}> <FormControl sx={{ minWidth: 180 }}> <InputLabel id="sortByLabel" size="small"> Sort By </InputLabel> Loading Loading @@ -357,23 +308,25 @@ export default function SearchAndFilterInput(props) { </span> </div> {pyGeoAPIFlag && ( {props.availableQueriables.length > 0 && ( <> <Divider/> <div className="panelSection panelBar"> <span> <FormControl sx={{ minWidth: 150 , minHeight: 40}}> <InputLabel id="selectQueryLabel" size="small" style={{paddingTop: '0.2rem'}}> <FormControl sx={{ minWidth: 180 , minHeight: 40}}> <InputLabel id="showPropertiesLabel" size="small" style={{paddingTop: '0.2rem'}}> Show Properties </InputLabel> <Select labelId="selectQueryLabel" label="Select Query" labelId="showPropertiesLabel" label="Show Properties" multiple value={selectedOptions} onChange={handleOptionChange} renderValue={(selected) => selected.join(', ')} style={{height: 43}} > {queryableTitles.map((title) => ( {props.availableQueriables.map((title) => ( <MenuItem key={title} value={title}> <Checkbox checked={selectedOptions.includes(title)} /> <ListItemText primary={title} /> Loading @@ -383,6 +336,7 @@ export default function SearchAndFilterInput(props) { </FormControl> </span> </div> </> )} <Divider/> Loading
src/components/presentational/Sidebar.jsx +6 −5 Original line number Diff line number Diff line Loading @@ -44,11 +44,12 @@ export default function Sidebar(props) { }; // State to hold the selected title const [selectedTitle, setSelectedTitle] = React.useState(""); const [availableQueriables, setAvailableQueriables] = React.useState(""); // Callback function to update selected title const updateSelectedTitle = (newTitle) => { setSelectedTitle(newTitle); const updateAvailableQueriables = (queriables) => { console.log(queriables); setAvailableQueriables(queriables); }; // State to hold the seleced queryables Loading @@ -72,7 +73,7 @@ export default function Sidebar(props) { setFilterString={setFilterString} targetName={props.target.name} target={props.target} selectedTitle={selectedTitle} availableQueriables={availableQueriables} UpdateQueryableTitles = {UpdateQueryableTitles} /> <FootprintResults Loading @@ -80,7 +81,7 @@ export default function Sidebar(props) { filterString={filterString} queryAddress={props.queryAddress} setQueryAddress={props.setQueryAddress} updateSelectedTitle={updateSelectedTitle} updateAvailableQueriables={updateAvailableQueriables} selectedQueryables = {updatedQueryableTitles} UpdateQueryableTitles = {UpdateQueryableTitles} /> Loading
src/js/FetchData.js +34 −3 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ export default async function Initialize(){ } // Combine data from Astro Web Maps and STAC API into one new object function organizeData(astroWebMaps, stacApiCollections, vectorApiCollections) { async function organizeData(astroWebMaps, stacApiCollections, vectorApiCollections) { // Initialize Objects let mapList = { "systems" : [] }; Loading Loading @@ -97,6 +97,8 @@ export default async function Initialize(){ let sysIndex = mapList.systems.map(sys => sys.name).indexOf(target.system); // ID the system. This seems to get the main planet of the system. // https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html // "A planet is always considered to be the 99th satellite of its own barycenter" if (target.naif % 100 === 99){ mapList.systems[sysIndex].naif = target.naif; } Loading @@ -113,7 +115,9 @@ export default async function Initialize(){ 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)") collection.dataType = "raster"; collection.querTitles = []; collection.title = collection.title.concat(" (Raster)"); myCollections.push(collection); } } Loading @@ -122,8 +126,33 @@ export default async function Initialize(){ // view the collection as GEOJSON let target_name = pycollection.id.split('/')[0]; if (target.name == target_name.toUpperCase()) { // Set links GeoSTAC needs later pycollection.links.find(link => link.rel === "items").href = "https://astrogeology.usgs.gov/pygeoapi" + pycollection.links.find(link => link.rel === "items").href; pycollection.itemsLink = "https://astrogeology.usgs.gov/pygeoapi" + pycollection.links.find(link => link.rel === "items").href; pycollection.queryablesLink = "https://astrogeology.usgs.gov/pygeoapi" + pycollection.links.find(link => link.rel === "queryables").href; // Fetch and await queriables fetchStatus[pycollection.queryablesLink] = "Not Started"; fetchPromise[pycollection.queryablesLink] = "Not Started"; jsonPromise[pycollection.queryablesLink] = "Not Started"; mapsJson[pycollection.queryablesLink] = []; ensureFetched(pycollection.queryablesLink); await ensureFetched(pycollection.queryablesLink); // put queryable titles in array let querData = mapsJson[pycollection.queryablesLink]; let querTitles = []; let querProps = querData.properties; for (const property in querProps) { if (querProps.hasOwnProperty(property) && querProps[property].hasOwnProperty("title")) { querTitles.push(querData.properties[property].title); } } // Add a specification to the title in order to show what kind of data the user is requesting pycollection.dataType = "vector"; pycollection.querTitles = querTitles; pycollection.title = pycollection.title.concat(" (Vector)"); myCollections.push(pycollection); } Loading Loading @@ -228,7 +257,9 @@ export default async function Initialize(){ await ensureFetched(stacApiCollections); await ensureFetched(vectorApiCollections); return organizeData(mapsJson[astroWebMaps], mapsJson[stacApiCollections], mapsJson[vectorApiCollections]); let organizedData = await organizeData(mapsJson[astroWebMaps], mapsJson[stacApiCollections], mapsJson[vectorApiCollections]); return organizedData; } aggregateMapList = await getStacAndAstroWebMapsData(); Loading