-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from PnX-SI/feat/promise
Feat(API): Add functions to retrieve occurrences from diff sources (GBIF, GN)
- Loading branch information
Showing
7 changed files
with
365 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,53 +19,31 @@ <h1 id="taxonName"></h1> | |
<div class="card-header">Liste de status</div> | ||
<ul id="listeStatuts" class="list-group list-group-flush"></ul> | ||
</div> | ||
<div class="card" style="width: 18rem"> | ||
<div class="card-header">Liste de status</div> | ||
<ul id="taxonList" class="list-group list-group-flush"></ul> | ||
</div> | ||
</div> | ||
</body> | ||
<script | ||
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" | ||
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" | ||
crossorigin="anonymous" | ||
></script> | ||
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@7/turf.min.js"></script> | ||
<script src="js/status.js"></script> | ||
<script src="js/utils.js"></script> | ||
<script src="js/media.js"></script> | ||
<script src="js/taxon.js"></script> | ||
<script src="js/config.js"></script> | ||
<script> | ||
const taxonData = { | ||
"Capra Ibex": { | ||
name: "Capra Ibex", | ||
cd_ref: 61098, | ||
gbifId: 2441055, | ||
count: 125, | ||
}, | ||
}; | ||
|
||
getTaxRefCdNom(taxonData["Capra Ibex"].gbifId).then(function (res) { | ||
console.log(res); | ||
}); | ||
const listeStatusUl = document.getElementById("listeStatuts"); | ||
document.getElementById("taxonName").innerHTML = | ||
taxonData["Capra Ibex"].name; | ||
|
||
getStatusForATaxon(taxonData["Capra Ibex"]).then(function (res) { | ||
res.status.forEach((element) => { | ||
const statusTypeAvailable = Object.keys(labels); | ||
statusTypeAvailable.forEach(function (statusType) { | ||
// if no data available for this status Type | ||
if (!element[statusType]) { | ||
return; | ||
} | ||
var li = document.createElement("li"); | ||
li.classList.add("list-group-item"); | ||
li.innerHTML = `<span class="badge bg-primary rounded-pill">${labels[statusType]}</span><span>${element[statusType]}</span>`; | ||
|
||
listeStatusUl.appendChild(li); | ||
}); | ||
wkt = | ||
"POLYGON ((3.6067457860489474 44.31735648705861, 3.6067235753826665 44.31753222361296, 3.606654037712057 44.31770147249114, 3.606539844959545 44.31785772946521, 3.606385385237379 44.31799498953319, 3.6061965942531686 44.318107977708294, 3.60598072721813 44.31819235175796, 3.605746080021263 44.3182448690979, 3.605501670386475 44.31826351142357, 3.6052568912711283 44.3182475622866, 3.605021149834159 44.31819763463273, 3.6048035058580408 44.31811564724215, 3.6046123235298966 44.318004750978425, 3.604454949972245 44.31786920768214, 3.6043374328830575 44.31771422636648, 3.6042642881382485 44.317545763013385, 3.6042383262856137 44.317370291667636, 3.6042605445924387 44.31719455562893, 3.604330088786867 44.317025308305304, 3.6044442859532793 44.31686905368802, 3.6045987473074517 44.31673179642029, 3.604787536893315 44.31661881106261, 3.60500339971254 44.31653443941854, 3.605238040517946 44.3164819237062, 3.6054824425586673 44.31646328198232, 3.6057272140334704 44.316479230603655, 3.605962948946621 44.316529156702984, 3.606180588508839 44.31661114173676, 3.606371769204977 44.31672203520022, 3.6065291441609757 44.316857575679116, 3.6066466654659757 44.31701255458916, 3.6067198166022463 44.31718101631465, 3.6067457860489474 44.31735648705861))"; | ||
// Get Taxon list | ||
getAllTopNTaxon(wkt, config.NB_MAX_TAXONS).then((listTaxons) => { | ||
completeTaxonsData(listTaxons).then((listTaxonsModified) => { | ||
console.log(listTaxonsModified); | ||
}); | ||
}); | ||
|
||
wkt = | ||
"POLYGON ((3.6067457860489474 44.31735648705861, 3.6067235753826665 44.31753222361296, 3.606654037712057 44.31770147249114, 3.606539844959545 44.31785772946521, 3.606385385237379 44.31799498953319, 3.6061965942531686 44.318107977708294, 3.60598072721813 44.31819235175796, 3.605746080021263 44.3182448690979, 3.605501670386475 44.31826351142357, 3.6052568912711283 44.3182475622866, 3.605021149834159 44.31819763463273, 3.6048035058580408 44.31811564724215, 3.6046123235298966 44.318004750978425, 3.604454949972245 44.31786920768214, 3.6043374328830575 44.31771422636648, 3.6042642881382485 44.317545763013385, 3.6042383262856137 44.317370291667636, 3.6042605445924387 44.31719455562893, 3.604330088786867 44.317025308305304, 3.6044442859532793 44.31686905368802, 3.6045987473074517 44.31673179642029, 3.604787536893315 44.31661881106261, 3.60500339971254 44.31653443941854, 3.605238040517946 44.3164819237062, 3.6054824425586673 44.31646328198232, 3.6057272140334704 44.316479230603655, 3.605962948946621 44.316529156702984, 3.606180588508839 44.31661114173676, 3.606371769204977 44.31672203520022, 3.6065291441609757 44.316857575679116, 3.6066466654659757 44.31701255458916, 3.6067198166022463 44.31718101631465, 3.6067457860489474 44.31735648705861))"; | ||
|
||
speciesList = {}; | ||
getGbifTaxon(wkt, speciesList, 0); | ||
</script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const config = { | ||
NB_MAX_TAXONS: 10, | ||
STATUS_LABELS: { | ||
worldRedList: "Liste Rouge Mondiale", | ||
europeanRedList: "Liste Rouge europeenne", | ||
nationalRedList: "Liste Rouge nationale", | ||
localRedList: "Liste Rouge locale", | ||
bonnConvention: "Convention de Bonn", | ||
bernConvention: "Convention de Bern", | ||
barcelonaConvention: "Convention de Barcelona", | ||
osparConvention: "Convention d'Ospar", | ||
hffDirective: "Directive Habitats Faune Flore", | ||
birdDirective: "Directive Oiseau", | ||
nationalProtection: "Protection nationale", | ||
regionalProtection: "Protection regionale", | ||
departementalProtection: "Protection départementale", | ||
nationalActionPlan: "Plan d'Action Nationale", | ||
scapNationale: "Stratégie nationale pour les aires protégées", | ||
scapRegionale: "Stratégie régionale pour les aires protégées", | ||
sensibilite: "Sensibilité", | ||
biogeoStatus: "Status biogeo", | ||
reglementation: "Réglementation", | ||
invasiveReglementation: "Réglementation invasive", | ||
prioriteActionPubliqueNationale: "Priorité d'action publique nationale", | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,20 @@ | ||
async function addMedia2Json(speciesDict) { | ||
console.log("addMedia2Json"); | ||
for(key in speciesDict) { | ||
url = 'https://api.gbif.org/v1/species/' + speciesDict[key].gbifId + '/media'; | ||
/** | ||
* Fetch the url of the first image for a given GBIF id. | ||
* @param {number} gbifId - GBIF id of the taxon | ||
* @returns {Promise<string>} - a promise resolving to the url of the first | ||
* image for the given taxon, or undefined if no image is found | ||
*/ | ||
function getMedias(gbifId) { | ||
url = "https://api.gbif.org/v1/species/" + gbifId + "/media"; | ||
|
||
await fetch(url,{method:'GET'}) | ||
.then(function(response) {return response.json(); }) | ||
.then(function(json) { | ||
// Media checking | ||
if (json.results.length > 0) { | ||
speciesDict[key].media = json.results[0].identifier; | ||
console.log(speciesDict[key].media + "<br>"); | ||
} | ||
}); | ||
console.log(key + "<br>"); | ||
console.log(url + "<br>"); | ||
} | ||
|
||
return speciesDict; | ||
return fetch(url, { method: "GET" }) | ||
.then(function (response) { | ||
return response.json(); | ||
}) | ||
.then(function (json) { | ||
// Media checking | ||
if (json.results.length > 0) { | ||
return json.results[0].identifier; | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,16 @@ | ||
const labels ={worldRedList: "Liste Rouge Mondiale", | ||
europeanRedList: "Liste Rouge europeenne", | ||
nationalRedList: "Liste Rouge nationale", | ||
localRedList: "Liste Rouge locale", | ||
bonnConvention: "Convention de Bonn", | ||
bernConvention: "Convention de Bern", | ||
barcelonaConvention: "Convention de Barcelona", | ||
osparConvention: "Convention d'Ospar", | ||
hffDirective: "Directive Habitats Faune Flore", | ||
birdDirective: "Directive Oiseau", | ||
nationalProtection: "Protection nationale", | ||
regionalProtection: "Protection regionale", | ||
departementalProtection: "Protection départementale", | ||
nationalActionPlan: "Plan d'Action Nationale", | ||
scapNationale: "Stratégie nationale pour les aires protégées", | ||
scapRegionale: "Stratégie régionale pour les aires protégées", | ||
sensibilite: "Sensibilité", | ||
biogeoStatus: "Status biogeo", | ||
reglementation: "Réglementation", | ||
invasiveReglementation: "Réglementation invasive", | ||
prioriteActionPubliqueNationale: "Priorité d'action publique nationale",} | ||
async function getStatusForATaxon(taxonData) { | ||
const reponse = await fetch(`https://taxref.mnhn.fr/api/taxa/${taxonData.cd_ref}/status/columns`); | ||
const status = await reponse.json(); | ||
return status._embedded | ||
/** | ||
* Given a taxonData object, fetch its status data from TaxRef API | ||
* @param {Object} taxonData - a taxon data object with a cd_ref property | ||
* @returns {Promise<Object[]>} - a list of status objects | ||
*/ | ||
function getStatusForATaxon(taxonData) { | ||
return fetch( | ||
`https://taxref.mnhn.fr/api/taxa/${taxonData.cd_ref}/status/columns` | ||
) | ||
.then((response) => { | ||
return response.json(); | ||
}) | ||
.then((json) => { | ||
return json._embedded?.status; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,143 @@ | ||
function getGbifTaxon(wkt, speciesList, page) { | ||
console.log("getGbifTaxon", page); | ||
const limit = 300; | ||
const offset = page * limit; | ||
geometry = wkt; | ||
fetch( | ||
"https://api.gbif.org/v1/occurrence/search?geometry=${geometry}&limit=${limit}&offset=${offset}" | ||
) | ||
.then(function (response) { | ||
return response.json(); | ||
}) | ||
.then(function (data) { | ||
data.results.forEach((element) => { | ||
occCount = (speciesList[element.species] || {})["occCount"] || 0; | ||
speciesList[element.species] = { | ||
gbifId: element.taxonKey, | ||
occCount: occCount + 1, | ||
}; | ||
}); | ||
const DEFAULT_NB_MAX_TAXONS = 10; | ||
|
||
console.log(speciesList); | ||
if (data.endOfRecords == false) { | ||
getGbifTaxon(wkt, speciesList, page + 1); | ||
} | ||
}) | ||
.catch(function (err) { | ||
console.log(err); | ||
/** | ||
* Fetch a page of taxon data from GBIF given a WKT string | ||
* @param {string} wkt - Well-Known Text representation of a polygon | ||
* @param {number} limit - number of results to return | ||
* @param {number} offset - offset of the first result | ||
* @returns {Promise<import('gbif-types').GBIFSearchResponse>} | ||
*/ | ||
function fetchApiTaxonGbif(wkt, limit, offset) { | ||
return fetch( | ||
`https://api.gbif.org/v1/occurrence/search?geometry=${wkt}&limit=${limit}&offset=${offset}` | ||
).then((response) => { | ||
return response.json(); | ||
}); | ||
} | ||
|
||
/** | ||
* Fetch the list of taxons from GBIF given a WKT string | ||
* @param {string} wkt - Well-Known Text representation of a polygon | ||
* @param {number} [nbMaxTaxons=DEFAULT_NB_MAX_TAXONS] - maximum number of results to return | ||
* @param {Object} [params={ limit: 300 }] - parameters to pass to the API | ||
* @returns {Promise<Array<{gbifId: number, occCount: number, species: string}>>} - a list of taxons with their occurrence count and GBIF id | ||
*/ | ||
function getGbifTaxon( | ||
wkt, | ||
nbMaxTaxons = DEFAULT_NB_MAX_TAXONS, | ||
params = { limit: 300 } | ||
) { | ||
return ( | ||
fetch(`https://api.gbif.org/v1/occurrence/search?geometry=${wkt}&limit=1`) | ||
.then((response) => { | ||
return response.json(); | ||
}) | ||
// Get total number of occurrences | ||
.then((data) => { | ||
return data.count; | ||
}) | ||
.then(async function (countOccurrence) { | ||
// Compute the number of pages we need to query | ||
const nbOfPages = Math.ceil(countOccurrence / params.limit); | ||
|
||
// Create a promise for each page | ||
let promises = []; | ||
for (let pageIndex = 0; pageIndex < nbOfPages; pageIndex++) { | ||
const offset = pageIndex * params.limit; | ||
promises.push(fetchApiTaxonGbif(wkt, params.limit, offset)); | ||
} | ||
let speciesList = {}; | ||
// Run all promises and await for the responses | ||
await Promise.all(promises).then((listOfData) => { | ||
listOfData | ||
.map((apiResult) => { | ||
return apiResult.results; | ||
}) | ||
// For each page | ||
.forEach((resultsPage) => { | ||
// For each occurrence retrieve the gbifID and increase occurrence count | ||
resultsPage.forEach((taxonData) => { | ||
occCount = | ||
(speciesList[taxonData.species] || {})["occCount"] || 0; | ||
speciesList[taxonData.species] = { | ||
gbifId: taxonData.taxonKey, | ||
occCount: occCount + 1, | ||
}; | ||
}); | ||
}); | ||
}); | ||
return speciesList; | ||
}) | ||
.then((taxonsData) => { | ||
let data = []; | ||
Object.keys(taxonsData).forEach((value) => { | ||
data.push([value, taxonsData[value]["occCount"]]); | ||
}); | ||
data.sort(function (a, b) { | ||
return b[1] - a[1]; | ||
}); | ||
data = data.slice(0, nbMaxTaxons).map((x) => { | ||
return x[0]; | ||
}); | ||
let newTaxonsData = []; | ||
data.forEach((key) => { | ||
newTaxonsData.push({ ...taxonsData[key], species: key }); | ||
}); | ||
return newTaxonsData; | ||
}) | ||
); | ||
} | ||
|
||
/** | ||
* Fetch a list of taxon data from the GTSI API given a WKT string | ||
* @param {string} wkt - Well-Known Text representation of a polygon | ||
* @param {number} [nbMaxTaxons=DEFAULT_NB_MAX_TAXONS] - number of results to return | ||
* @returns {Promise<import('gbif-types').GBIFTaxon[]>} | ||
*/ | ||
function getPgRestTaxon(wkt, nbMaxTaxons = DEFAULT_NB_MAX_TAXONS) { | ||
const geometry = wkt; | ||
return ( | ||
fetch( | ||
`https://dev-gtsi.cevennes-parcnational.net/api/rpc/get_taxa_list?in_wkt=${geometry}&in_limit=${nbMaxTaxons}` | ||
) | ||
.then((response) => { | ||
return response.json(); | ||
}) | ||
// Get total number of occurrences | ||
.then((data) => { | ||
return data.map( | ||
({ | ||
count_occ: occCount, | ||
species_name: species, | ||
species_key: gbifId, | ||
...rest | ||
}) => ({ | ||
occCount, | ||
species, | ||
gbifId, | ||
...rest, | ||
}) | ||
); | ||
}) | ||
); | ||
} | ||
|
||
/** | ||
* Get the top N taxons from both the GTSI API and the GBIF API given a WKT string | ||
* @param {string} wkt - Well-Known Text representation of a polygon | ||
* @param {number} [nbMaxTaxons=DEFAULT_NB_MAX_TAXONS] - number of results to return | ||
* @returns {Promise<import('gbif-types').GBIFTaxon[]>} - a list of taxons with their occurrence count and GBIF id | ||
*/ | ||
function getAllTopNTaxon(wkt, nbMaxTaxons = DEFAULT_NB_MAX_TAXONS) { | ||
let promises = [ | ||
getPgRestTaxon(wkt, nbMaxTaxons), | ||
getGbifTaxon(wkt, nbMaxTaxons), | ||
]; | ||
return Promise.all(promises).then((listOfData) => { | ||
const allData = [...listOfData[0], ...listOfData[1]]; | ||
allData.sort(function (a, b) { | ||
return b["occCount"] - a["occCount"]; | ||
}); | ||
return Promise.resolve(allData.slice(0, nbMaxTaxons)); | ||
}); | ||
} |
Oops, something went wrong.