Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
| procedures:recuperation_et_integration_de_donnees_depuis_le_gbif [2026/01/31 22:39] – dmaillard | procedures:recuperation_et_integration_de_donnees_depuis_le_gbif [2026/02/03 07:59] (Version actuelle) – dmaillard | ||
|---|---|---|---|
| Ligne 73: | Ligne 73: | ||
| } | } | ||
| } | } | ||
| + | |||
| + | Autres configurations : | ||
| + | * [[Configuration Musée des Confluences]] | ||
| + | * [[Configuration Observations.org]] | ||
| Ligne 96: | Ligne 100: | ||
| Une fois les données récupérées, | Une fois les données récupérées, | ||
| - | cut -f 1, | + | cut -f 1,6,8,18,22, |
| cut -f 1,4 / | cut -f 1,4 / | ||
| | | ||
| - | Enfin, deux tables de destination sont créées dans la base de données (au premier usage), puis alimentées par ces données | + | Enfin, deux tables de destination sont créées dans la base de données (au premier usage) : |
| CREATE SCHEMA pinv_gbif; | CREATE SCHEMA pinv_gbif; | ||
| + | | ||
| CREATE TABLE pinv_gbif.tmp_gbif_data ( | CREATE TABLE pinv_gbif.tmp_gbif_data ( | ||
| gbif_id bigint primary key, | gbif_id bigint primary key, | ||
| Ligne 108: | Ligne 112: | ||
| " | " | ||
| basis_of_record varchar(255), | basis_of_record varchar(255), | ||
| - | | + | |
| + | recorded_by | ||
| individual_count varchar(255), | individual_count varchar(255), | ||
| sex varchar(255), | sex varchar(255), | ||
| Ligne 132: | Ligne 137: | ||
| | | ||
| CREATE TABLE pinv_gbif.cor_multimedia ( | CREATE TABLE pinv_gbif.cor_multimedia ( | ||
| - | gbif_id | + | gbif_id |
| - | media_url text NULL | + | media_url text |
| ); | ); | ||
| + | | ||
| + | Puis alimentées par les données récupérées : | ||
| + | |||
| + | sudo su postgres | ||
| + | psql -d < | ||
| + | \copy pinv_gbif.tmp_gbif_data | ||
| + | FROM PROGRAM 'tail -n +2 / | ||
| + | WITH ( | ||
| + | FORMAT text, | ||
| + | DELIMITER E' | ||
| + | ); | ||
| + | | ||
| + | \copy pinv_gbif.cor_multimedia | ||
| + | FROM PROGRAM 'tail -n +2 / | ||
| + | WITH ( | ||
| + | FORMAT text, | ||
| + | DELIMITER E' | ||
| + | ); | ||
| + | |||
| + | ==== Étape intermédiaire iNaturalist ==== | ||
| + | iNaturalist génère des uuid pour ses observations, | ||
| + | |||
| + | Le choix du Pôle invertébrés est donc : | ||
| + | * de récupérer les occurrences de taxons depuis le GBIF pour partager les mêmes scripts avec d' | ||
| + | * de récupérer les identifiants de données iNaturalist | ||
| + | * de récupérer uniquement les uuid de ces données sur l'API v2 de iNaturalist (pas optimal, mais moindre mal), afin de ne pas générer de nouveaux uuid à ces données | ||
| + | |||
| + | Les identifiants des données iNaturalist récupérées auprès du GBIF sont isolés : | ||
| + | |||
| + | SELECT id_synthese, | ||
| + | JOIN taxonomie.taxref t ON t.cd_nom=s.cd_nom | ||
| + | WHERE id_dataset=3125; | ||
| + | |||
| + | Ces id_inaturalist sont ensuite utilisés dans R, avec le script suivant, pour récupérer les uuids des données dans iNaturalist, | ||
| + | |||
| + | fetch_inat_uuid <- function( | ||
| + | df, | ||
| + | id_col = " | ||
| + | uri_col = " | ||
| + | uuid_col = " | ||
| + | batch_size = 50, | ||
| + | sleep_sec = 1 | ||
| + | ) { | ||
| + | | ||
| + | library(httr) | ||
| + | library(jsonlite) | ||
| + | library(progress) | ||
| + | | ||
| + | # typer les id_inaturalist en integer | ||
| + | df[[id_col]] <- as.integer(trimws(df[[id_col]])) | ||
| + | | ||
| + | if (!uuid_col %in% names(df)) { | ||
| + | df[[uuid_col]] <- NA_character_ | ||
| + | } | ||
| + | | ||
| + | if (!uri_col %in% names(df)) { | ||
| + | df[[uri_col]] <- NA_character_ | ||
| + | } | ||
| + | | ||
| + | ids_to_fetch <- df[[id_col]][is.na(df[[uuid_col]])] | ||
| + | | ||
| + | batches <- split(ids_to_fetch, | ||
| + | | ||
| + | pb <- progress_bar$new( | ||
| + | format = " | ||
| + | total = length(batches), | ||
| + | clear = FALSE, | ||
| + | width = 60 | ||
| + | ) | ||
| + | | ||
| + | for (batch_ids in batches) { | ||
| + | | ||
| + | res <- try( | ||
| + | GET( | ||
| + | " | ||
| + | query = list( | ||
| + | id = paste(batch_ids, | ||
| + | fields=" | ||
| + | per_page = length(batch_ids) | ||
| + | ), | ||
| + | user_agent(" | ||
| + | ), | ||
| + | silent = TRUE | ||
| + | ) | ||
| + | | ||
| + | if (!inherits(res, | ||
| + | pb$tick() | ||
| + | Sys.sleep(sleep_sec * 2) | ||
| + | next | ||
| + | } | ||
| + | | ||
| + | json <- fromJSON( | ||
| + | content(res, | ||
| + | flatten = TRUE | ||
| + | ) | ||
| + | | ||
| + | if (length(json$results) > 0) { | ||
| + | uuids <- setNames( | ||
| + | json$results$uuid, | ||
| + | as.integer(json$results$id) | ||
| + | ) | ||
| + | | ||
| + | uris <- setNames( | ||
| + | json$results$uri, | ||
| + | as.integer(json$results$id) | ||
| + | ) | ||
| + | | ||
| + | idx <- match(as.integer(names(uuids)), | ||
| + | df[[uuid_col]][idx] <- uuids | ||
| + | | ||
| + | idx <- match(as.integer(names(uris)), | ||
| + | df[[uri_col]][idx] <- uris | ||
| + | } | ||
| + | | ||
| + | pb$tick() | ||
| + | Sys.sleep(sleep_sec) | ||
| + | } | ||
| + | | ||
| + | return(df) | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | inaturalist_uuids <- fetch_inat_uuid( | ||
| + | inaturalist_ids, | ||
| + | id_col | ||
| + | uuid_col = " | ||
| + | batch_size = 50, | ||
| + | sleep_sec = 1 | ||
| + | ) | ||
| + | | ||
| + | Ces résultats sont ensuite exportés de R, importés dans la base de données postgresql dans une table pinv_gbif.cor_uuid_inaturalist, | ||
| + | | ||
| ==== Postgresql : Insérer ou actualiser les données en synthèse ==== | ==== Postgresql : Insérer ou actualiser les données en synthèse ==== | ||
| + | |||
| + | À partir des données stockées dans les tables temporaires, | ||
| + | |||
| + | Il faut ensuite disposer d'une source " | ||
| + | |||
| + | INSERT INTO gn_synthese.t_sources() | ||
| + | VALUES (); | ||
| + | |||
| + | Pour permettre l' | ||
| + | |||
| + | ALTER TABLE gn_synthese.synthese ADD CONSTRAINT WHERE id_source=X; | ||
| + | |||
| + | Une fois le ou les jeux de données préparés et bien identifiés (uuid), créer la fonction suivante : | ||
| + | |||
| + | TODO | ||
| + | | ||
| + | Puis déclencher l' | ||
| + | |||
| + | SELECT pinv_gbif.upsert_gbif_data(); | ||