4Création d’une base réglementaire à partir de CNLEGIS
4.1 Objet
Le processus de création, modification ou disparition des aires protégées passe par des lois, décrets et arrêtés officels. Ces éléments réglementaires sont dispersés dans divers textes juridiques, que nous allons ici collecter et consolider à partir de la base du Centre National d’Informatoin et de Documentation Legislative et Juridique (CNLEGIS). Cette instance centralise les textes réglementaires à Madagascar et propose un moteur de recherche permettant de trouver les documents pertinents en fonction de recherches full-text.
4.2 Extraction des textes pertinents
La base CNLEGIS ne propose pas d’API, donc l’extraction a dû être réalisée manuellement. Nous avons simplement entré la requête “aire protégée”, ce qui a retourné 131 résultats. Nous avons extrait les 14 pages web correspondantes. Le code ci-dessous extrait l’information pertinente, la nettoie et la restitue sous forme de tableaux.
Code
library(rvest)library(tidyverse)library(sf)# Specify the source repository data_dir <-"sources/"# Directory containing the HTML filesinput_dir <-paste0(data_dir, "Décrets/CNLEGIS")# Columns to selectkeep_columns <-c("DATE(S)", "DATE TEXTES", "TEXTE(S)", "TYPE", "NUM TEXTE", "NUM", "OBJET","OBJET MG", "NUM JO", "DATE JO", "DATE JO FR", "PAGE JO", "ETAT", "NOTE(S)","NOTES MG", "DOC PDF FR", "DOC PDF MG", "MINISTERE(S)", "id", "HTML FR", "HTML MG")keep_types <-c("Constitution", "Loi constitutionnelle", "Loi organique", "Loi","Ordonnance", "Décret", "Arrêté", "Circulaire", "Décision","Instruction", "Note", "Délibération", "Arrêt", "Avis", "Palmarès","Procès verbal", "Exposé des motifs de la loi", "Jugement", "Déclaration")# Function to clean column namesclean_column_names <-function(names) { names %>%str_replace_all("\\(|\\)", "") %>%# Remove parenthesesstr_replace_all(" ", "_") %>%# Replace spaces with underscoresstr_to_lower() # Convert to lowercase}# Function to extract the desired table from a single HTML fileextract_table <-function(file_path) {# Read the HTML file html <-read_html(file_path)# Extract the table table <- html %>%html_node("table#Lst_docs") %>%html_table(fill =TRUE)# Select the relevant columns selected_columns <- table %>%select(all_of(keep_columns)) %>%filter(TYPE %in% keep_types)colnames(selected_columns) <-clean_column_names(colnames(selected_columns))# Ensure all columns are converted to text selected_columns<- selected_columns %>%mutate(across(everything(), as.character))return(selected_columns)}# Get a list of all HTML files in the directoryhtml_files <-list.files(input_dir, pattern ="\\.html$", full.names =TRUE)# Apply the extraction function to all filesall_results <-map_dfr(html_files, extract_table) %>%mutate(date_txt =dmy(date_textes), # Convertit les datesdate_jo =dmy(date_jo)) %>%relocate(date_txt, date_jo, .before =everything()) # place les dates au débutall_results |>select(-html_fr, -html_mg, -objet_mg, -textes, -num, -doc_pdf_fr, -doc_pdf_mg) |> DT::datatable(height =10)
4.3 Classification par type de réglement
Pour mieux organiser les données extraites, les textes sont classifiés selon le type de transformation qu’elles opèrent (création, modification, prorogation, etc.) à l’aide de règles de typologie.
Code
# Add typology columnsclass_results <- all_results %>%mutate(creation_definitive =str_detect( textes, regex("(?<!en )(création|crétion de l'aire protégée)", ignore_case =TRUE)),modifiant =str_detect(textes, regex("modifiant", ignore_case =TRUE)),prorogation =str_detect(textes, regex("prorog", ignore_case =TRUE)),delegation_gestion =str_detect( textes, regex("délégation de gestion", ignore_case =TRUE)),mise_protection_temporaire =str_detect( textes, regex("protection temporaire", ignore_case =TRUE)),nomination =str_detect(textes, regex("nomination", ignore_case =TRUE))) %>%mutate(total_true =rowSums(select(., creation_definitive:nomination), na.rm =TRUE),concatenated_true =pmap_chr(select(., creation_definitive:nomination),~paste(names(which(c(...))), collapse =", ") ),.before =everything() ) %>%filter(!(total_true ==0)) %>%filter(!(total_true ==1& nomination)) %>%# On enlève le copil Sydneyfilter(!(str_detect(textes, "fonctionnement du Comité de Pilotage"))) %>%filter(!(str_detect(textes, "fonctionnement de la Commission"))) %>%filter(!(str_detect(textes, "organisation du Comité")))arr_creation_pre2008 <- class_results %>%filter(year(date_jo) <2008& (date_jo) >2008& (mise_protection_temporaire | creation_definitive)) %>%arrange(date_jo)
Ces deux textes concernent une liste très étendue de sites potentiels, qui ne sont pas nommément listés dans le texte. On a juste une carte (peu précise) et une somme de zones concernées (en nombre et en surface).
4.4 Appariement des noms d’aires protégées entre CNLEGIS et SAPM
On va avoir besoin de rapprocher ces textes juridiques des données spatiales SAPM et WDPA. On doit le faire à partir des noms des aires protégées, mais ceux-ci ne sont pas normalisés. Une première étape essentielle consiste à extraire ces noms et à les nettoyer avant de procéder à la recherche de correspondances avec les bases spatiales.
Code
class_results <- class_results %>%mutate(pa =str_extract( textes, regex("[\"«](.*?)[\"»,]|nommée\\s*(.*?)[»,]", ignore_case =TRUE) ),pa =ifelse(is.na(pa),str_extract( textes, regex("nommée\\s*(.*?)[\"]", ignore_case =TRUE) ), pa ),pa =ifelse(str_detect(textes, "respectivement"),str_extract( textes,regex("respectivement\\s+(.*?)(?=\\.|N°|ETAT)", ignore_case =TRUE) ), pa ),pa =str_replace(pa, "\"Complexe des Aires", "Complexe des Aires"), pa =str_remove(pa, "^nommée\\s*"), # Supprime "nommée"pa =str_remove(pa, "^respectivement\\s*"), # Supprime "nommée"pa =str_remove(pa, "(?<=\")[^\"«]*$"), # Supprime tout après le 2e guillemetpa =str_remove_all(pa, "[\"«»]"), # Supprime les quotespa =str_trim(pa), # Supprime les espaces en troppa =str_remove(pa, ",$"),pa =str_remove(pa, "^'"),.before = textes )
Une fois les noms des aires protégées concernées extraites de chaque texte, on les compare aux noms de la base SAPM. On le fait tout d’abord automatiquement avec un algorithme d’appariement approximatif (“fuzzy matching”), qui tient compte des variations d’orthographe ou des dénominations multiple.