Compare commits
14
Commits
fdad4a0961
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a659403162 | ||
|
|
80af0334a8 | ||
|
|
a5f9afc6aa | ||
|
|
e5f2a11443 | ||
|
|
cb8b602e4a | ||
|
|
e095efbac9 | ||
|
|
c34bbb97f4 | ||
|
|
a96ba72d47 | ||
|
|
e70e8ed483 | ||
|
|
e7d13c70a9 | ||
|
|
2630b7fc4b | ||
|
|
85b1c5ee87 | ||
|
|
47df9ccc34 | ||
|
|
7c97930547 |
@@ -0,0 +1,110 @@
|
|||||||
|
# Actualisation de la BDC Status INPN à partir d'un dossier ZIP
|
||||||
|
## 1. Download BDC Status INPN
|
||||||
|
``` sh
|
||||||
|
# TAXREF V17.0 - Version du 15 novembre 2024
|
||||||
|
wget https://inpn.mnhn.fr/docs-web/docs/download/232324
|
||||||
|
mv ./232324 ./BDC-Statuts-v17.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.Correction des formats de fichiers
|
||||||
|
La dernière version de l'INPN fournis 2 fichier dont 1 fichier Excel.
|
||||||
|
La mise à jour requière UNIQEMENT des fichiers CSV.
|
||||||
|
- Décompresser le ZIP
|
||||||
|
- Ouvrir le fichier Excel et enregistrer-le en CSV (encodage UTF8, séparateur virgule)
|
||||||
|
- Reformer le ZIP
|
||||||
|
|
||||||
|
## 3. Intégration de la nouvelle BDC Statut
|
||||||
|
- Connectez-vous à votre serveur GéoNature et ouvrez un terminal python
|
||||||
|
``` sh
|
||||||
|
source geonature/backend/venv/bin/activate
|
||||||
|
geonature shell
|
||||||
|
```
|
||||||
|
- Exécuter le script suivant en adaptant la variable `BASE_URL` (chemin d'accès vers le zip de la BDC Statut)
|
||||||
|
``` py
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from zipfile import ZipFile
|
||||||
|
import importlib.resources
|
||||||
|
|
||||||
|
from apptax.taxonomie.commands.utils import truncate_bdc_statuts
|
||||||
|
from apptax.database import db
|
||||||
|
from apptax.taxonomie.commands.utils import (
|
||||||
|
copy_from_csv,
|
||||||
|
refresh_taxref_vm,
|
||||||
|
populate_bdc_statut_cor_text_area,
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
BASE_URL = "/home/geonatureadmin/tmp"
|
||||||
|
zipfile = "BDC-Statuts-v17.zip"
|
||||||
|
status_types_file = "BDC-Statuts-v17/BDC_STATUTS_TYPES_17.csv"
|
||||||
|
status_file = "BDC-Statuts-v17/BDC_STATUTS_17.csv"
|
||||||
|
|
||||||
|
truncate_bdc_statuts()
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
archive = ZipFile(os.path.join(BASE_URL, zipfile), "r")
|
||||||
|
with archive.open(status_file) as f:
|
||||||
|
logger.info("Insert BDC statuts…")
|
||||||
|
copy_from_csv(
|
||||||
|
f,
|
||||||
|
"bdc_statut",
|
||||||
|
dest_cols=(
|
||||||
|
"cd_nom",
|
||||||
|
"cd_ref",
|
||||||
|
"cd_sup",
|
||||||
|
"cd_type_statut",
|
||||||
|
"lb_type_statut",
|
||||||
|
"regroupement_type",
|
||||||
|
"code_statut",
|
||||||
|
"label_statut",
|
||||||
|
"rq_statut",
|
||||||
|
"cd_sig",
|
||||||
|
"cd_doc",
|
||||||
|
"lb_nom",
|
||||||
|
"lb_auteur",
|
||||||
|
"nom_complet_html",
|
||||||
|
"nom_valide_html",
|
||||||
|
"regne",
|
||||||
|
"phylum",
|
||||||
|
"classe",
|
||||||
|
"ordre",
|
||||||
|
"famille",
|
||||||
|
"group1_inpn",
|
||||||
|
"group2_inpn",
|
||||||
|
"lb_adm_tr",
|
||||||
|
"niveau_admin",
|
||||||
|
"cd_iso3166_1",
|
||||||
|
"cd_iso3166_2",
|
||||||
|
"full_citation",
|
||||||
|
"doc_url",
|
||||||
|
"thematique",
|
||||||
|
"type_value",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info("Populate BDC statuts…")
|
||||||
|
db.session.execute(
|
||||||
|
importlib.resources.read_text("apptax.migrations.data", "taxonomie_bdc_statuts.sql")
|
||||||
|
)
|
||||||
|
|
||||||
|
populate_bdc_statut_cor_text_area(logger)
|
||||||
|
refresh_taxref_vm()
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
exit()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Reformer les liens BDC Statut vs areas
|
||||||
|
``` sh
|
||||||
|
geonature taxref link-bdc-statut-to-areas
|
||||||
|
# Rendre accessible les status concernés par un département
|
||||||
|
# L'argument -d peut être répété dans le cas de plusieurs département
|
||||||
|
# Il est possible qu'il faille au préalable désactiver tous les status de la table bdc_statut_text
|
||||||
|
geonature taxref enable-bdc-statut-text --clean -d 38
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Intégration de liste d'Alerte _`MAISON`_
|
||||||
|
Dans le cas de l'Isère il s'agit de liste d'alerte départementale
|
||||||
|
|
||||||
|
## 1. Les fonctions éventuellement à modifier
|
||||||
|
Le script incrémente de nouveaux types de statuts dans la bdd :
|
||||||
|
- def insert_status_alerte (l.25) : Intégration du statut `alerte départementale` dans la table `taxonomie.bdc_statut_type`
|
||||||
|
|cd_type_statut|lb_type_statut|regroupement_type|thematique|type_value|
|
||||||
|
|-|-|-|-|-|
|
||||||
|
|'AL'|'Liste d''alerte départementale'|'Alerte'|'STATUTS'|'VALUE'|
|
||||||
|
- def insert_status_values (l.42) : Intégration de libellés de statut nom présent dans la table `taxonomie.bdc_statut_values`
|
||||||
|
|code_statut|label_statut|
|
||||||
|
|-|-|
|
||||||
|
|'RE'|'Disparue au niveau départemental'|
|
||||||
|
|'AS-1'|'Quasi menacée (localisées sans signe de déclin)'|
|
||||||
|
|'AS-2'|'Quasi menacée (répandues mais en déclin)'|
|
||||||
|
|'AS-3'|'Quasi menacée (répandues, déclin à confirmer)'|
|
||||||
|
|
||||||
|
## 2. Le code à personaliser
|
||||||
|
La personalisation impérative est située à partir de la ligne 231 du script :
|
||||||
|
- l.235 : Import/Définition de la connexion à la bdd GéoNature.
|
||||||
|
En cas de définition de la connexion, ajoutez/completez le code ci-dessous :
|
||||||
|
``` py
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.engine import URL
|
||||||
|
gn_user = 'XXXX'
|
||||||
|
gn_pwd = 'XXXX'
|
||||||
|
gn_adr = 'XXXX'
|
||||||
|
gn_base = 'XXXX'
|
||||||
|
gn_url = URL.create("postgresql+psycopg2", username=gn_user, password=gn_pwd, host=gn_adr, database=gn_base)
|
||||||
|
con_gn = create_engine(gn_url)
|
||||||
|
```
|
||||||
|
- l.242 : Chemin vers le fichier des listes d'alertes à importer. Le fichier doit être un Excel contenant à minima les colonnes suivantes :
|
||||||
|
|CD_NOM|Statut|Source|Source_url|
|
||||||
|
|-|-|-|-|
|
||||||
|
|
||||||
|
ATTENTION : les lignes la `Source_url` est None ou NA (non remplie) seront ignorés.
|
||||||
|
La colonne `Statut` recense les CODES STATUTS.
|
||||||
|
_Pour exemple, vous pouvez vous référez au fichier utilisé en Isère : `listes_alertes_isère.xlsx`_
|
||||||
|
- l.244 : Définir l'échelle administratif des listes à implémenter.
|
||||||
|
- l.246 : Définir le nom du niveau adminsitratif concerné.
|
||||||
|
- l.248 : Définir le code SIG du niveau adminnistratif. N'hésiter pas à vous référer à ceux déjà présent dans la table `taxonomie.bdc_statut_text`
|
||||||
|
- l.253 : Dictionnaire des listes de statut présent dans le fichier Excel. A définir sous le format suivant
|
||||||
|
``` json
|
||||||
|
{
|
||||||
|
'Source' : {
|
||||||
|
'id_doc': Valeur du cd_doc à implémenter dans la table taxonomie.bdc_statut_text
|
||||||
|
'id_values': [Liste de l'ensemble des statut concernés par la source.]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -155,15 +155,22 @@ def test_status_text(con,col,cd_doc):
|
|||||||
with con.begin() as cnx:
|
with con.begin() as cnx:
|
||||||
return cnx.execute(sql).one()[0]
|
return cnx.execute(sql).one()[0]
|
||||||
|
|
||||||
def insert_statut_text(con,cd_doc,doc):
|
def insert_statut_text(con,cd_doc,doc,cd_sig,lb_adm_tr,niveau_admin):
|
||||||
if test_data(con,'bdc_statut_text','cd_doc',cd_doc['id_doc']) > 0:
|
if test_data(con,'bdc_statut_text','cd_doc',cd_doc['id_doc']) > 0:
|
||||||
# if test_status_text(con,'cd_doc',cd_doc) > 0:
|
|
||||||
print('ALERTE TEXT STATUS ALREADY EXISTS : ',doc)
|
print('ALERTE TEXT STATUS ALREADY EXISTS : ',doc)
|
||||||
else:
|
else:
|
||||||
sql = '''
|
sql = '''
|
||||||
INSERT INTO {sch}.{tab} (cd_type_statut,cd_doc,cd_sig,niveau_admin,lb_adm_tr,doc_url,enable) VALUES
|
INSERT INTO {sch}.{tab} (cd_type_statut,cd_doc,cd_sig,niveau_admin,lb_adm_tr,doc_url,enable) VALUES
|
||||||
('AL',{cd_doc},'INSEED38','Département','Isère','{doc}',TRUE)
|
('AL',{cd_doc},'{cdsig}','{lb_adm}','{niv_adm}','{doc}',TRUE)
|
||||||
;'''.format(sch='taxonomie',tab='bdc_statut_text',cd_doc=cd_doc['id_doc'],doc=doc)
|
;'''.format(
|
||||||
|
sch='taxonomie',
|
||||||
|
tab='bdc_statut_text',
|
||||||
|
cd_doc=cd_doc['id_doc'],
|
||||||
|
doc=doc,
|
||||||
|
cdsig=cd_sig,
|
||||||
|
lb_adm=lb_adm_tr,
|
||||||
|
niv_adm=niveau_admin
|
||||||
|
)
|
||||||
with con_gn.begin() as cnx:
|
with con_gn.begin() as cnx:
|
||||||
cnx.execute(sql)
|
cnx.execute(sql)
|
||||||
|
|
||||||
@@ -244,11 +251,26 @@ if __name__ == "__main__":
|
|||||||
# Dictionnaire des listes d’alerte à intégrer,
|
# Dictionnaire des listes d’alerte à intégrer,
|
||||||
# identifiant et codes status respectivement concernés
|
# identifiant et codes status respectivement concernés
|
||||||
cd_doc = {
|
cd_doc = {
|
||||||
'Statut_de_conservation_des_poissons_et_écrevisses_en_Isère_2015':{'id_doc':999990,'id_values':['RE','CR','EN','VU','NT','LC','DD','NA',]},
|
'Statut_de_conservation_des_poissons_et_écrevisses_en_Isère_2015':{
|
||||||
'Liste_d’alerte_sur_les_orthoptères_menacés_en_Isère_2014':{'id_doc':999991,'id_values':['RE','CR','EN','VU','AS-1','AS-2','AS-3','LC','DD','NA']},
|
'id_doc':999990,
|
||||||
'Statuts_de_conservation_de_la_faune_sauvage_en_isere_2016':{'id_doc':999992,'id_values':['RE','CR','EN','VU','NT','LC','DD','NA','NE',]},
|
'id_values':['RE','CR','EN','VU','NT','LC','DD','NA',]
|
||||||
'Liste_rouge_des_Odonates_de_l’Isère_2013':{'id_doc':999993,'id_values':['RE','CR','EN','VU','NT','LC','DD','NA',]},
|
},
|
||||||
'Liste_rouge_des_lépidoprere_rhopaloceres_et_zygenes_de_l’Isère_2015':{'id_doc':999994,'id_values':['RE','CR','EN','VU','NT','LC','DD','NA','NE','EX']},
|
'Liste_d’alerte_sur_les_orthoptères_menacés_en_Isère_2014':{
|
||||||
|
'id_doc':999991,
|
||||||
|
'id_values':['RE','CR','EN','VU','AS-1','AS-2','AS-3','LC','DD','NA']
|
||||||
|
},
|
||||||
|
'Statuts_de_conservation_de_la_faune_sauvage_en_isere_2016':{
|
||||||
|
'id_doc':999992,
|
||||||
|
'id_values':['RE','CR','EN','VU','NT','LC','DD','NA','NE',]
|
||||||
|
},
|
||||||
|
'Liste_rouge_des_Odonates_de_l’Isère_2013':{
|
||||||
|
'id_doc':999993,
|
||||||
|
'id_values':['RE','CR','EN','VU','NT','LC','DD','NA',]
|
||||||
|
},
|
||||||
|
'Liste_rouge_des_lépidoprere_rhopaloceres_et_zygenes_de_l’Isère_2015':{
|
||||||
|
'id_doc':999994,
|
||||||
|
'id_values':['RE','CR','EN','VU','NT','LC','DD','NA','NE','EX']
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
df = (pd.read_excel(file,keep_default_na=False)
|
df = (pd.read_excel(file,keep_default_na=False)
|
||||||
@@ -261,7 +283,7 @@ if __name__ == "__main__":
|
|||||||
df = df.loc[df.doc_url!='']
|
df = df.loc[df.doc_url!='']
|
||||||
for d in df.source.unique():
|
for d in df.source.unique():
|
||||||
doc_url = df.loc[df.source==d,'doc_url'].unique()[0]
|
doc_url = df.loc[df.source==d,'doc_url'].unique()[0]
|
||||||
insert_statut_text(con_gn,cd_doc[d],doc_url)
|
insert_statut_text(con_gn,cd_doc[d],doc_url,cd_sig,lb_adm_tr,niveau_admin)
|
||||||
|
|
||||||
# INSERTION dans la table bdc_statut_taxons
|
# INSERTION dans la table bdc_statut_taxons
|
||||||
# Boucle sur chaque taxon. Peu prendre quelques minutes.
|
# Boucle sur chaque taxon. Peu prendre quelques minutes.
|
||||||
Binary file not shown.
@@ -0,0 +1,61 @@
|
|||||||
|
# Exctraction de la BDC Statut à partir d'une liste de taxon.
|
||||||
|
Le fichier source doit contenir à minima une colone contenant les `cd_nom` ou `cd_ref` concernés par l'extraction à réaliser.
|
||||||
|
Dans le cas où il contient d'autres colonnes (date, nombre, observateur, ...), celles-ci seront jointes au sein des feuillets `pivot_table` et `pivot_libel` ; cf.ci-dessous.
|
||||||
|
|
||||||
|
|
||||||
|
L'export obtenu se compose des feuillets suivants :
|
||||||
|
- <ins>v_bdc_status :</ins> c'est un export qusi pure de la vue `taxonomie.v_bdc_status`.
|
||||||
|
|cd_nom|cd_ref|regne|phylum|classe|ordre|famille|group1_inpn|group2_inpn|group3_inpn|nom_vern|nom_complet|nom_valide|lb_nom|rq_statut|code_statut|cd_type_statut|label_statut|full_citation|doc_url|
|
||||||
|
|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
|
||||||
|
- <ins>pivot_table :</ins> Il correspond à l'export de la vue `taxonomie.v_bdc_status` retourner pour avoir les codes status en colonnes et non en ligne en face de chaque espèce (1 ligne = 1 espèce).
|
||||||
|
Au sein de ce feuillet, il est possible qu'une espèce pour un statut, possède plusieurs codes statut. Ces codes seront alors écrit entre `[]` (C'est souvent le cas pour les listes LRN concernant les oiseaux). Dans ce cas, référez-vous au feuillet `v_bdc_status` en filtrant sur l'espèce concerné pour en savoir plus. C'est souvent lié au fait que l'espèce possède un statut différent en fonction des conditions d'observations (exemple : Hiverant, Nicheur, ...).
|
||||||
|
Les colonnes récupérées sont les suivantes :
|
||||||
|
- <ins>AL :</ins> Liste d'alerte départementale
|
||||||
|
- <ins>BARC :</ins> Convention de Barcelone
|
||||||
|
- <ins>BERN :</ins> Convention de Berne
|
||||||
|
- <ins>BONN :</ins> Convention de Bonn
|
||||||
|
- <ins>OSPAR :</ins> Convention OSPAR
|
||||||
|
- <ins>DH :</ins> Directive Habitat
|
||||||
|
- <ins>DO :</ins> Directive Oiseaux
|
||||||
|
- <ins>LRE :</ins> Liste rouge européenne
|
||||||
|
- <ins>LRM :</ins> Liste rouge mondiale
|
||||||
|
- <ins>LRN :</ins> Liste rouge nationale
|
||||||
|
- <ins>LRR_AURA :</ins> Liste rouge régionale AURA
|
||||||
|
- <ins>LRR_RA :</ins> Liste rouge régionale (ancienne région)
|
||||||
|
- <ins>PNA :</ins> Plan national en cours
|
||||||
|
- <ins>exPNA :</ins> Plan national terminé
|
||||||
|
- <ins>PAPNAT :</ins> Priorité action publique nationale
|
||||||
|
- <ins>POM :</ins> Protection COM
|
||||||
|
- <ins>PD :</ins> Protection départementale
|
||||||
|
- <ins>PN :</ins> Protection nationale
|
||||||
|
- <ins>PR :</ins> Protection régionale
|
||||||
|
- <ins>REGLII :</ins> Interdiction d'introduction
|
||||||
|
- <ins>REGLLUTTE :</ins> Lutte contre certaines espèces
|
||||||
|
- <ins>REGL :</ins> Réglementation
|
||||||
|
- <ins>REGLSO :</ins> Réglementation sans objet
|
||||||
|
- <ins>SCAP NAT :</ins> SCAP nationale
|
||||||
|
- <ins>SCAP REG :</ins> SCAP régionale
|
||||||
|
- <ins>SENSDEP :</ins> Sensibilité départementale
|
||||||
|
- <ins>SENSNAT :</ins> Sensibilité nationale
|
||||||
|
- <ins>SENSREG :</ins> Sensibilité régionale
|
||||||
|
- <ins>ZDET :</ins> ZNIEFF Déterminantes
|
||||||
|
|
||||||
|
**ATTENTION :** Il est normal de ne pas retrouver tous les statuts cités à chaque export car les types de statuts non concernées par la liste d'espèce soumises ne figureront pas dans le tableau.
|
||||||
|
- <ins>pivot_libel :</ins> Identique à `pivot_table` mais contenant les intitulés des statuts à la place des codes.
|
||||||
|
- <ins>dic_type_statut :</ins> Dictionnaire des types de status concerné par l'extraction.
|
||||||
|
|
||||||
|
## Configuration du fichier
|
||||||
|
Les variables à modifier se situe de l.215 à l.225 :
|
||||||
|
- <ins>l.215 :</ins> Import/Définition de la connexion à la bdd GéoNature. En cas de définition de la connexion, ajoutez/completez le code ci-dessous :
|
||||||
|
``` py
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.engine import URL
|
||||||
|
gn_user = 'XXXX'
|
||||||
|
gn_pwd = 'XXXX'
|
||||||
|
gn_adr = 'XXXX'
|
||||||
|
gn_base = 'XXXX'
|
||||||
|
gn_url = URL.create("postgresql+psycopg2", username=gn_user, password=gn_pwd, host=gn_adr, database=gn_base)
|
||||||
|
con_gn = create_engine(gn_url)
|
||||||
|
```
|
||||||
|
- <ins>l.219 :</ins> Variable de configuration de lecture du fichier Excel contenant l'ensemble des taxons.
|
||||||
|
- <ins>l.225 :</ins> Intitulé de la colonne listant les codes taxonomiques.
|
||||||
@@ -37,6 +37,12 @@ def get_status(lst,con):
|
|||||||
;""".format(cd_nom = tuple(lst))
|
;""".format(cd_nom = tuple(lst))
|
||||||
return pd.read_sql_query(sql,con)
|
return pd.read_sql_query(sql,con)
|
||||||
|
|
||||||
|
def get_type_status(con):
|
||||||
|
sql = """
|
||||||
|
SELECT * FROM taxonomie.bdc_statut_type
|
||||||
|
;"""
|
||||||
|
return pd.read_sql_query(sql,con)
|
||||||
|
|
||||||
def get_api_status(api,cd_nom:int):
|
def get_api_status(api,cd_nom:int):
|
||||||
res = requests.api.get('%s/%i'%(api,cd_nom))
|
res = requests.api.get('%s/%i'%(api,cd_nom))
|
||||||
if res.status_code == 200:
|
if res.status_code == 200:
|
||||||
@@ -225,6 +231,8 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# Récupération des statuts
|
# Récupération des statuts
|
||||||
df = get_status(taxlist[cd_col].astype(str),con_gn)
|
df = get_status(taxlist[cd_col].astype(str),con_gn)
|
||||||
|
typ = get_type_status(con_gn)
|
||||||
|
typ = typ[typ.cd_type_statut.isin(df.cd_type_statut.unique())]
|
||||||
|
|
||||||
# Distinction LRR [old vs new] région
|
# Distinction LRR [old vs new] région
|
||||||
is_lrr = df.cd_type_statut == 'LRR'
|
is_lrr = df.cd_type_statut == 'LRR'
|
||||||
@@ -287,3 +295,8 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
# writer.save()
|
# writer.save()
|
||||||
print('pivot_libel OK !')
|
print('pivot_libel OK !')
|
||||||
|
typ.to_excel(
|
||||||
|
writer,sheet_name='dic_type_statut',index=False
|
||||||
|
)
|
||||||
|
# writer.save()
|
||||||
|
print('dic_type_statut OK !')
|
||||||
Reference in New Issue
Block a user