PnX-SI / GeoNature

Application de saisie et de synthèse des observations faune et flore
GNU General Public License v3.0
99 stars 101 forks source link

Fonction de recherche de taxon sans CD_REF / CD_NOM #445

Open sig-pnrnm opened 5 years ago

sig-pnrnm commented 5 years ago

Nous en avons discuté lors du Worshop GeoNature v2 : j'ai découvert l'existance d'un webservice de l'INPN qui permet de retourner les CD_REF / CD_NOM d'un taxon à partir d'une chaine de texte (Nom binominal).

(au passage, je veux bien la référence, car je ne l'ai pas notée)

Sous SERENA, nous avions aussi une fonction de ce type, nommée "Trouve Taxon".

Si jamais une gentil développeur se sentait le courage pour intégrer cette fonction dans le coeur de GeoNature (je pense bien évidemment à quelqu'un :wink: ), ça permettrait de gagner en performance pour l'intégration de données externes ou historiques, par exemple.

Pour info, le résultat d'une recherche "Trouve Taxon" de SERENA retourne un nom complet (nom binomial + auteur + année), un pourcentage de correspondance, et les CD_NOM / CD_REF correspondants.

Ca permet de vérifier avant une importation si les taxons seront bien gérés et de corriger les taxons problématiques.

TheoLechemia commented 5 years ago

C'est ici pour tester : https://taxref.mnhn.fr/taxref-web/api/doc après il y a aussi "taxref-match" ou il faut demander un compte: https://taxref.mnhn.fr/taxref-match/spring_security_login Et aussi un service du GBIF, bien intéressant (sans cd_ref par contre): https://www.gbif.org/tools/species-lookup

A garder sous la main pour un futur module d'import en effet.

gildeluermoz commented 5 years ago

Tu peux tester ça :

CREATE OR REPLACE FUNCTION taxonomie.matching_with_taxref(myname text)
  RETURNS TABLE(cdnom integer, cdref integer, nomcomplet text, nomvalide text, matching text) AS
$BODY$
-- function that return the best matching name in taxref from the given name
-- RETURN Table type with cdnom integer, cdref integer, nomcomplet text, nomvalide text, matching text
-- USAGE :
-- SELECT taxonomie.matching_with_taxref('Bufo bufo');
-- SELECT (taxonomie.matching_with_taxref('Bufo bufo')).cdnom;
-- SELECT (taxonomie.matching_with_taxref('Bufo bufo')).cdref;
-- SELECT (taxonomie.matching_with_taxref('Bufo bufo')).nomcomplet;
-- SELECT (taxonomie.matching_with_taxref('Bufo bufo')).cdref, (taxonomie.matching_with_taxref('Bufo bufo')).nomvalide;
-- SELECT (taxonomie.matching_with_taxref('ufo ')).matching;
-- SELECT myfield, 
--        (taxonomie.matching_with_taxref(myfield)).cdnom, 
--        (taxonomie.matching_with_taxref(myfield)).nomcomplet
-- FROM mytable
  BEGIN
    IF (SELECT cd_nom AS cd_nom FROM taxonomie.taxref WHERE nom_complet::text = $1 LIMIT 1) IS NOT NULL THEN
      RETURN QUERY
        SELECT cd_nom AS cd_nom, cd_ref AS cdref, nom_complet::text AS nomcomplet, nom_valide::text AS nomvalide, 'equal'::text AS matching
        FROM taxonomie.taxref
        WHERE nom_complet::text = $1;
    ELSIF (SELECT cd_nom AS cd_nom FROM taxonomie.taxref WHERE nom_complet::text ILIKE $1 LIMIT 1) IS NOT NULL THEN
      RETURN QUERY
        SELECT cd_nom AS cd_nom, cd_ref AS cdref, nom_complet::text AS nomcomplet, nom_valide::text AS nomvalide, 'ilike'::text AS matching
        FROM taxonomie.taxref
        WHERE nom_complet::text ILIKE $1;
    ELSIF (SELECT cd_nom AS cd_nom FROM taxonomie.taxref WHERE nom_complet::text ~* ('^' || $1) LIMIT 1) IS NOT NULL THEN
      RETURN QUERY
        SELECT cd_nom AS cd_nom, cd_ref AS cdref, nom_complet::text AS nomcomplet, nom_valide::text AS nomvalide, 'begin'::text AS matching
        FROM taxonomie.taxref
        WHERE nom_complet::text ~* ('^' || $1);
    ELSIF (SELECT cd_nom AS cd_nom FROM taxonomie.taxref WHERE nom_complet::text ~* ('.*' || $1 || '.*') LIMIT 1) IS NOT NULL THEN
      RETURN QUERY
        SELECT cd_nom AS cd_nom, cd_ref AS cdref, nom_complet::text AS nomcomplet, nom_valide::text AS nomvalide, 'content'::text AS matching
        FROM taxonomie.taxref
        WHERE nom_complet::text ~* ('.*' || $1 || '.*');
    END IF;
  END;
$BODY$
LANGUAGE plpgsql IMMUTABLE
COST 100
ROWS 1000;

Mais les perfs sont carrément pourrie même si tu créé un index

CREATE INDEX i_taxref_nom_complet
  ON taxonomie.taxref
  USING btree
  (nom_complet COLLATE pg_catalog."default");

Si qq'un a une idée pour les perfs ou pour améliorer la fonction ...

camillemonchicourt commented 3 years ago

Je relaie ici une info de @Amegilla reçu de l'INPN sur le service Taxref-match qu'on a déjà utilisé :

Les administrateurs de données des plateformes du SINP peuvent être confrontés à la transmission de données de producteurs sans l’identifiant de l’espèce du référentiel TAXREF (CD_NOM).

Cela nécessite alors un traitement (parfois lourd) pour rattacher les espèces citées avec le référentiel.

Afin de faciliter ce traitement, nous proposons l’usage de l’outil TAXREF-Match : https://taxref.mnhn.fr/taxref-match

Cet outil permet de charger une liste de noms scientifiques d’espèces (jusqu'à 10 000) et d’obtenir en retour des propositions de CD_NOM.

Le service est également disponible sous forme de web-service dans l'API TAXREF (documentation ici : https://taxref.mnhn.fr/taxref-web/api/doc), bien que la réponse soit moins complète que sur l'application dédiée. Par exemple : https://taxref.mnhn.fr/api/taxa/fuzzyMatch?term=buffo%20buffo%20linné%201758


On a testé déjà depuis quelques temps, intéressant mais à faire à la main sous forme de fichier. Ou sinon avec l'API mais donc pas le plus simple à utiliser et pas toujours le plus performant.

Du coup nous avons fait une demande d'ouverture du code source de Taxref-match à l'UMS Patrinat pour ne pas refaire de notre côté les traitements directement dans la BDD qu'ils ont déjà travaillé de leur côté.

A suivre.

DonovanMaillard commented 3 years ago

Attention quand même, lors de test, ça a généré aussi de belles erreurs, qui ne sont pas du tout négligeables. Par exemple en nous remplacant nos grandes sauterelles vertes en cigales, qu'on a eu a des altitudes totalement incohérentes. Le nom de la cigale matchait avant celui de la sauterelle.

Dans le cas de vrais synonymes, il reste des erreurs, que j'avais fait remonter.

A ce stade de mon coté j'ai fait une fonction simple pour traiter les noms latins bien orthographiés, ça répond déjà à 90% des cas...

Amegilla commented 3 years ago

Toujours ce synonyme de tettigonia cantans pour une cigale qui mets la pagaille partout... pareil chez nous :)

DonovanMaillard commented 3 years ago

C'est l'un des exemples en effet. Mais je l'ai eu sur un ou deux autres taxons que je n'ai plus en mémoire...