Commit c49c4617 authored by Benjam's avatar Benjam
Browse files

Resolve "ajouter nouveaux regroupements"

parent 6d05fc7a
This diff is collapsed.
id_regroupement_communes;nom_regroupement_communes;categorie_regroupement_communes
CARRE_METROPOLITAIN_LYONNAIS;Carré métropolitain de Lyon;CARRE_METROPOLITAIN_LYONNAIS
PNR-01;PNR des Alpilles;PNR
PNR-02;PNR des Ardennes;PNR
PNR-03;PNR d'Armorique;PNR
PNR-04;PNR de l'Aubrac;PNR
PNR-05;PNR de l'Avesnois;PNR
PNR-06;PNR Baie de Somme Picardie Maritime;PNR
PNR-07;PNR des Ballons des Vosges;PNR
PNR-08;PNR des Baronnies provençales;PNR
PNR-09;PNR des Boucles de la Seine;PNR
PNR-10;PNR de la Brenne;PNR
PNR-11;PNR de Brière;PNR
PNR-12;PNR de Camargue;PNR
PNR-13;PNR des Caps et Marais d'Opale;PNR
PNR-14;PNR des Causses du Quercy;PNR
PNR-15;PNR de Chartreuse;PNR
PNR-16;PNR Corbières-Fenouillèdes;PNR
PNR-17;PNR de Corse;PNR
PNR-18;PNR du Doubs Horloger;PNR
PNR-19;PNR de la Forêt d'Orient;PNR
PNR-20;PNR du Golfe du Morbihan;PNR
PNR-21;PNR des Grands Causses;PNR
PNR-22;PNR de Guyane;PNR
PNR-23;PNR du Gâtinais français;PNR
PNR-24;PNR du haut Jura;PNR
PNR-25;PNR du Haut-Languedoc;PNR
PNR-26;PNR de la Haute-Vallée de Chevreuse;PNR
PNR-27;PNR des Landes de Gascogne;PNR
PNR-28;PNR Livradois-Forez;PNR
PNR-29;PNR Loire-Anjou-Touraine;PNR
PNR-30;PNR de Lorraine;PNR
PNR-31;PNR du Luberon;PNR
PNR-32;PNR des Marais du Cotentin et du Bessin;PNR
PNR-33;PNR du marais poitevin;PNR
PNR-34;PNR de Martinique;PNR
PNR-35;PNR du Massif des Bauges;PNR
PNR-36;PNR Medoc;PNR
PNR-37;PNR de Millevaches en Limousin;PNR
PNR-38;PNR du Mont Ventoux;PNR
PNR-39;PNR de la Montagne de Reims;PNR
PNR-40;PNR des monts d'Ardèche;PNR
PNR-41;PNR du Morvan;PNR
PNR-42;PNR de la Narbonnaise en Méditerranée;PNR
PNR-43;PNR Normandie-Maine;PNR
PNR-44;PNR Oise-Pays de France;PNR
PNR-45;PNR du Perche;PNR
PNR-46;PNR du Pilat;PNR
PNR-47;PNR des Préalpes d'Azur;PNR
PNR-48;PNR des Pyrénées ariégeoises;PNR
PNR-49;PNR des Pyrénées catalanes;PNR
PNR-50;PNR Périgord-Limousin;PNR
PNR-51;PNR du Queyras;PNR
PNR-52;PNR de la Sainte-Baume;PNR
PNR-53;PNR Scarpe-Escaut;PNR
PNR-54;PNR du Vercors;PNR
PNR-55;PNR du Verdon;PNR
PNR-56;PNR du Vexin français;PNR
PNR-57;PNR des Volcans d'Auvergne;PNR
PNR-58;PNR des Vosges du Nord;PNR
SCOT-001;SCOT AGGLOMERATION LYONNAISE;SCOT
SCOT-002;SCOT BEAUJOLAIS;SCOT
SCOT-003;SCOT BUCOPA;SCOT
SCOT-004;SCOT DE LA BOUCLE DU RHONE EN DAUPHINE;SCOT
SCOT-005;SCOT DE LA DOMBES;SCOT
SCOT-006;SCOT DES MONTS DU LYONNAIS;SCOT
SCOT-007;SCOT DES RIVES DU RHONE;SCOT
SCOT-008;SCOT DU ROANNAIS;SCOT
SCOT-009;SCOT LOIRE CENTRE;SCOT
SCOT-010;SCOT NORD ISERE;SCOT
SCOT-011;SCOT OUEST LYONNAIS;SCOT
SCOT-012;SCOT SUD LOIRE;SCOT
SCOT-013;SCOT VAL DE SAONE - DOMBES;SCOT
\ No newline at end of file
This diff is collapsed.
......@@ -18,7 +18,8 @@ from crater.reglages import (
CHEMIN_CRATER_DATA_SOURCES,
CHEMIN_SOURCE_COMMUNES_ET_ARRONDISSEMENTS, CHEMIN_DOSSIER_SOURCE_GEOMETRIES_COMMUNES,
CHEMIN_SOURCE_MOUVEMENTS_COMMUNES,
CHEMIN_SOURCE_EPCIS, CHEMIN_SOURCE_DEPARTEMENTS, CHEMIN_SOURCE_REGIONS, CHEMIN_SOURCE_CODES_POSTAUX,
CHEMIN_SOURCE_EPCIS, FICHIERS_REGROUPEMENTS_COMMUNES, CHEMIN_SOURCE_DEPARTEMENTS, CHEMIN_SOURCE_REGIONS,
CHEMIN_SOURCE_CODES_POSTAUX,
CHEMIN_SOURCE_POPULATION_TOTALE, CHEMIN_SOURCE_POPULATION_TOTALE_HISTORIQUE,
CHEMIN_SOURCE_POPULATION_AGRICOLE,
CHEMIN_SOURCE_ARTIFICIALISATION, CHEMIN_SOURCE_NB_LOGEMENTS, CHEMIN_SOURCE_NB_LOGEMENTS_VACANTS,
......@@ -127,7 +128,7 @@ def lancer_calcul_referentiel_territoires():
CHEMIN_SOURCE_DEPARTEMENTS,
CHEMIN_SOURCE_REGIONS,
CHEMIN_SOURCE_CODES_POSTAUX,
DOSSIER_CONFIG / "regroupements_geographiques",
FICHIERS_REGROUPEMENTS_COMMUNES,
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
stocker_duree_etape('CALCUL_REFERENTIEL_TERRITOIRES', time.time() - debut)
......
......@@ -16,6 +16,27 @@ CHEMIN_SOURCE_EPCIS = Path(
CHEMIN_CRATER_DATA_SOURCES /
"insee/geographie/epcis/2021/Intercommunalite-Metropole_au_01-01-2021.xlsx"
)
CHEMIN_SOURCE_REGROUPEMENTS_COMMUNES = Path(
CHEMIN_CRATER_DATA_SOURCES /
"regroupements_geographiques"
)
FICHIERS_REGROUPEMENTS_COMMUNES = [
{'categorie_regroupement_communes': 'BV2012',
'fichier_source': CHEMIN_SOURCE_REGROUPEMENTS_COMMUNES / "bassins_de_vie_2012" / "2021" / "com2021.xlsx"},
{'categorie_regroupement_communes': 'PN',
'fichier_source': CHEMIN_SOURCE_REGROUPEMENTS_COMMUNES / "parcs_nationaux" / "2021" / "com2021.xlsx"},
{'categorie_regroupement_communes': 'PNR',
'fichier_source': CHEMIN_SOURCE_REGROUPEMENTS_COMMUNES / "parcs_naturels_regionaux" / "2021" / "com2021.xlsx"},
{'categorie_regroupement_communes': 'PAYS_PETR',
'fichier_source': CHEMIN_SOURCE_REGROUPEMENTS_COMMUNES / "pays_et_petr" / "2021" / "com2021.xlsx"},
{'categorie_regroupement_communes': 'SCOT',
'fichier_source': CHEMIN_SOURCE_REGROUPEMENTS_COMMUNES / "urbalyon" / "2021" / "scot.xlsx"},
{'categorie_regroupement_communes': 'AM',
'fichier_source': CHEMIN_SOURCE_REGROUPEMENTS_COMMUNES / "urbalyon" / "2021" / "interscot.xlsx"},
{'categorie_regroupement_communes': 'AM',
'fichier_source': CHEMIN_SOURCE_REGROUPEMENTS_COMMUNES / "urbalyon" / "2021" / "carre_metropolitain.xlsx"}
]
CHEMIN_SOURCE_GEOMETRIES_DEPARTEMENTS = CHEMIN_CRATER_DATA_SOURCES / 'france_geojson' / '2018' / 'departements.geojson'
CHEMIN_SOURCE_DEPARTEMENTS = Path(
CHEMIN_CRATER_DATA_SOURCES /
......
from pathlib import Path
from typing import Tuple
from typing import Tuple, List, Dict
import numpy as np
import pandas as pd
from pandas import DataFrame
......@@ -26,7 +26,7 @@ def calculer_referentiel_territoires(
chemin_fichier_departements: Path,
chemin_fichier_regions: Path,
chemin_fichier_codes_postaux: Path,
chemin_dossier_regroupements_communes: Path,
fichiers_regroupements_communes: List[Dict[str, str]],
chemin_dossier_output: Path
) -> None:
sources_territoires = _charger_sources_territoires(
......@@ -36,7 +36,7 @@ def calculer_referentiel_territoires(
chemin_fichier_departements,
chemin_fichier_regions,
chemin_fichier_codes_postaux,
chemin_dossier_regroupements_communes
fichiers_regroupements_communes
)
territoires = _generer_referentiel_territoires(
sources_territoires
......@@ -379,7 +379,7 @@ def _charger_sources_territoires(
chemin_fichier_departements: Path,
chemin_fichier_regions: Path,
chemin_fichier_codes_postaux: Path,
chemin_dossier_regroupements_communes: Path
fichiers_regroupements_communes: List[Dict[str, str]]
) -> DictDataFrames:
log.info("##### CHARGEMEMENT DES SOURCES DU REFERENTIEL TERRITOIRES #####")
......@@ -390,16 +390,17 @@ def _charger_sources_territoires(
departements = chargeur_departements.charger(chemin_fichier_departements)
regions = chargeur_regions.charger(chemin_fichier_regions)
codes_postaux = chargeur_codes_postaux.charger(chemin_fichier_codes_postaux)
regroupements_communes = chargeur_regroupements_communes.charger_regroupements_communes(chemin_dossier_regroupements_communes)
composition_regroupements_communes = chargeur_regroupements_communes.charger_composition_regroupements_communes(chemin_dossier_regroupements_communes)
composition_regroupements_communes = composition_regroupements_communes.merge(regroupements_communes.loc[:, ['nom_regroupement_communes', 'id_regroupement_communes']], on = 'nom_regroupement_communes', how='left')
composition_regroupements_communes = chargeur_regroupements_communes.charger_composition_regroupements_communes(fichiers_regroupements_communes)
composition_regroupements_communes = _ajouter_nouveau_departement_Rhone(composition_regroupements_communes, communes)
outils_territoires.verifier_absence_na(composition_regroupements_communes, 'id_commune', 'id_regroupement_communes')
communes, epcis = _traiter_communes_sans_epci(communes, epcis)
communes, arrondissements, mouvements_communes, epcis, regroupements_communes, composition_regroupements_communes, departements, regions, codes_postaux = _supprimer_DROMs(
communes, arrondissements, mouvements_communes, epcis, regroupements_communes, composition_regroupements_communes, departements, regions, codes_postaux
communes, arrondissements, mouvements_communes, epcis, composition_regroupements_communes, departements, regions, codes_postaux = _supprimer_DROMs(
communes, arrondissements, mouvements_communes, epcis, composition_regroupements_communes, departements, regions, codes_postaux
)
regroupements_communes = composition_regroupements_communes.loc[:, ['id_regroupement_communes', 'nom_regroupement_communes', 'categorie_regroupement_communes']].drop_duplicates()
return {
'communes': communes,
......@@ -414,6 +415,21 @@ def _charger_sources_territoires(
}
def _ajouter_nouveau_departement_Rhone(
composition_regroupements_communes: DataFrame,
communes: DataFrame
) -> DataFrame:
communes_departement_Rhone_sans_metropole_Lyon = communes.loc[(communes.id_departement == "D-69") & (communes.id_epci != "E-200046977"), ['id_commune', 'nom_commune']]
communes_departement_Rhone_sans_metropole_Lyon['id_regroupement_communes'] = 'ND-69D'
communes_departement_Rhone_sans_metropole_Lyon['nom_regroupement_communes'] = 'Nouveau-Rhône'
communes_departement_Rhone_sans_metropole_Lyon['categorie_regroupement_communes'] = 'NOUVEAU-DEPARTEMENT'
composition_regroupements_communes = pd.concat([composition_regroupements_communes,
communes_departement_Rhone_sans_metropole_Lyon])
return composition_regroupements_communes
def _traiter_communes_sans_epci(communes: DataFrame, epcis: DataFrame) -> Tuple[DataFrame, DataFrame]:
communes.loc[communes.id_epci == "E-ZZZZZZZZZ", 'id_epci'] = np.nan
return communes, epcis.query('id_epci != "E-ZZZZZZZZZ"')
......@@ -424,7 +440,6 @@ def _supprimer_DROMs(
arrondissements: DataFrame,
mouvements_communes: DataFrame,
epcis: DataFrame,
regroupements_communes: DataFrame,
composition_regroupements_communes: DataFrame,
departements: DataFrame,
regions: DataFrame,
......@@ -437,10 +452,9 @@ def _supprimer_DROMs(
mouvements_communes = mouvements_communes.loc[~mouvements_communes['id_commune_initial'].str[2:4].isin(NUMEROS_DEPARTEMENTS_DROM)]
epcis = epcis.loc[epcis['id_epci'].isin(communes.id_epci.dropna())]
composition_regroupements_communes = composition_regroupements_communes.loc[composition_regroupements_communes['id_commune'].isin(communes.id_commune)]
regroupements_communes = regroupements_communes.loc[~regroupements_communes['nom_regroupement_communes'].isin(['PNR de Guyane', 'PNR de Martinique'])]
departements = departements.loc[~departements['id_region'].str[2:4].isin(["{:02}".format(num) for num in NUMEROS_REGIONS_HORS_DROM])]
regions = regions.loc[~regions['id_region'].str[2:4].isin(["{:02}".format(num) for num in NUMEROS_REGIONS_HORS_DROM])]
codes_postaux = codes_postaux.loc[~codes_postaux['id_commune_ou_arrondissement'].str[2:4].isin(NUMEROS_DEPARTEMENTS_DROM)]
return communes, arrondissements, mouvements_communes, epcis, regroupements_communes, composition_regroupements_communes, departements, regions, codes_postaux
return communes, arrondissements, mouvements_communes, epcis, composition_regroupements_communes, departements, regions, codes_postaux
......@@ -21,6 +21,10 @@ def charger_geometries_communes(
geometries_communes = _corriger_code_insee_Bernwiller(geometries_communes)
elif chemin_dossier.name == 'communes-20210101':
geometries_communes = _corriger_code_insee_Les_Trois_Lacs(geometries_communes)
elif chemin_dossier.name == 'geometries_communes':
pass
else:
raise ValueError("ERREUR lors du chargement des géométries des communes. Le fichier source n'est pas connu. Il faut l'ajouter en renseignant si besoin les traitements à effectuer")
return geometries_communes
......
from pathlib import Path
from typing import Dict, List
import pandas as pd
from pandas import DataFrame
from crater.crater_logger import log
from crater.territoires.outils import traduire_code_insee_vers_id_commune_crater, verifier_absence_doublons
from crater.territoires.outils import traduire_code_insee_vers_id_commune_crater
def charger_regroupements_communes(chemin_dossier: Path) -> DataFrame:
def charger_composition_regroupements_communes(fichiers: List[Dict[str, str]]) -> DataFrame:
fichier = chemin_dossier / "regroupements_communes.csv"
df = pd.DataFrame(columns = ['id_regroupement_communes', 'nom_regroupement_communes', 'categorie_regroupement_communes'])
df = pd.DataFrame(columns=['id_commune', 'nom_commune', 'id_regroupement_communes', 'nom_regroupement_communes', 'categorie_regroupement_communes'])
log.info(" => Chargement des regroupements de communes depuis %s", fichier)
df = pd.concat([df,
pd.read_csv(
fichier,
sep=';',
dtype={
'id_regroupement_communes': 'str',
'nom_regroupement_communes': 'str',
'categorie_regroupement_communes': 'str'
},
na_values=['']
)
])
for f in fichiers:
categorie_regroupement_communes = f['categorie_regroupement_communes']
fichier_source = f['fichier_source']
log.info(" => Chargement de la composition des regroupements de communes %s depuis %s", categorie_regroupement_communes, fichier_source)
df_a_ajouter = pd.read_excel(
fichier_source,
sheet_name=0,
usecols='A:D',
skiprows=4,
dtype='str',
na_values=['']
)
df_a_ajouter.columns = ['id_commune', 'nom_commune', 'id_regroupement_communes', 'nom_regroupement_communes']
df_a_ajouter = _dupliquer_communes_appartenant_a_plusieurs_regroupements(categorie_regroupement_communes, fichier_source, df_a_ajouter)
df_a_ajouter = df_a_ajouter.loc[~df_a_ajouter['id_regroupement_communes'].isnull()]
df_a_ajouter['id_regroupement_communes'] = categorie_regroupement_communes + '-' + df_a_ajouter['id_regroupement_communes']
df_a_ajouter['categorie_regroupement_communes'] = categorie_regroupement_communes
df = pd.concat([df, df_a_ajouter])
verifier_absence_doublons(df, 'id_regroupement_communes')
verifier_absence_doublons(df, 'nom_regroupement_communes')
_traduire_code_insee_vers_id_crater(df)
return df
def _dupliquer_communes_appartenant_a_plusieurs_regroupements(categorie_regroupement_communes, fichier_source, df):
if categorie_regroupement_communes == 'PNR':
if fichier_source.name == 'com2021.xlsx':
df = _dupliquer_commune_Porte_de_Savoie_appartenant_a_2_PNR(df)
else:
raise ValueError("ERREUR lors du chargement des PNRs. Le fichier source n'est pas connu. Il faut l'ajouter en renseignant si besoin les traitements à effectuer")
return df
def charger_composition_regroupements_communes(chemin_dossier: Path) -> DataFrame:
df = pd.DataFrame(columns = ['id_commune', 'nom_commune', 'nom_regroupement_communes'])
for f in [x for x in chemin_dossier.glob('*.csv') if (x.is_file() and x.name != "regroupements_communes.csv")]:
log.info(" => Chargement de la composition des regroupements de communes depuis %s", f)
df = pd.concat([df,
pd.read_csv(
f,
sep=';',
dtype={
'INSEE_COM': 'str',
'NOM_COM': 'str',
'NOM_REGROUPEMENT': 'str'
},
na_values=['']
).rename(
columns={
'INSEE_COM': 'id_commune',
'NOM_COM': 'nom_commune',
'NOM_REGROUPEMENT': 'nom_regroupement_communes'
},
errors='raise'
)
])
_traduire_code_insee_vers_id_crater(df)
def _dupliquer_commune_Porte_de_Savoie_appartenant_a_2_PNR(df) -> DataFrame:
#dans le fichier des PNR de l'observatoire des territoires, la commune Porte-de-Savoie (73151) appartient à 2 PNR et n'apparait que sur une ligne
mask_commune = df.id_commune == '73151'
df.loc[mask_commune, 'id_regroupement_communes'] = df.loc[mask_commune].id_regroupement_communes.str.split(' et ')
df.loc[mask_commune, 'nom_regroupement_communes'] = df.loc[mask_commune].nom_regroupement_communes.str.split(' et ')
df = df.explode(['id_regroupement_communes','nom_regroupement_communes'])
return df
......@@ -65,3 +57,4 @@ def charger_composition_regroupements_communes(chemin_dossier: Path) -> DataFram
def _traduire_code_insee_vers_id_crater(regroupements_communes: DataFrame) -> DataFrame:
regroupements_communes.id_commune = traduire_code_insee_vers_id_commune_crater(regroupements_communes.id_commune)
return regroupements_communes
INSEE_COM;NOM_COM;NOM_REGROUPEMENT
32145;Gée-Rivière;Le PAT monocommunal du Gée-Rivière
32145;Gée-Rivière;Le PAT interdepartemental D-32 (3 communes) D-40 (2 communes)
32333;Projan(scission2020);Le PAT interdepartemental D-32 (3 communes) D-40 (2 communes)
32424;Ségos(fusion2017);Le PAT interdepartemental D-32 (3 communes) D-40 (2 communes)
40001;Aire-sur-l'Adour;Le PAT interdepartemental D-32 (3 communes) D-40 (2 communes)
40146;Latrille;Le PAT interdepartemental D-32 (3 communes) D-40 (2 communes)
\ No newline at end of file
id_regroupement_communes;nom_regroupement_communes;categorie_regroupement_communes
PAT-1;Le PAT monocommunal du Gée-Rivière;PAT
PAT-2;Le PAT interdepartemental D-32 (3 communes) D-40 (2 communes);PAT
SCOT-1;Le SCoT monocommunal de Paris;SCOT
SCOT-2;Le SCoT monocommunal de Gée-Rivière;SCOT
SCOT-3;Le SCoT interdepartemental D-32 (3 communes) D-40 (2 communes);SCOT
\ No newline at end of file
INSEE_COM;NOM_COM;NOM_REGROUPEMENT
75056;Paris;Le SCoT monocommunal de Paris
32145;Gée-Rivière;Le SCoT monocommunal de Gée-Rivière
32145;Gée-Rivière;Le SCoT interdepartemental D-32 (3 communes) D-40 (2 communes)
32333;Projan(scission2020);Le SCoT interdepartemental D-32 (3 communes) D-40 (2 communes)
32424;Ségos(fusion2017);Le SCoT interdepartemental D-32 (3 communes) D-40 (2 communes)
40001;Aire-sur-l'Adour;Le SCoT interdepartemental D-32 (3 communes) D-40 (2 communes)
40146;Latrille;Le SCoT interdepartemental D-32 (3 communes) D-40 (2 communes)
\ No newline at end of file
......@@ -24,7 +24,10 @@ class TestTerritoires(unittest.TestCase):
CHEMIN_INPUT_DATA / DOSSIER_REFERENTIEL_TERRITOIRES / 'departements.csv',
CHEMIN_INPUT_DATA / DOSSIER_REFERENTIEL_TERRITOIRES / 'regions.csv',
CHEMIN_INPUT_DATA / DOSSIER_REFERENTIEL_TERRITOIRES / 'codes_postaux.csv',
CHEMIN_INPUT_DATA / DOSSIER_REFERENTIEL_TERRITOIRES / 'regroupements_geographiques',
[{'categorie_regroupement_communes': 'PAT',
'fichier_source': CHEMIN_INPUT_DATA / DOSSIER_REFERENTIEL_TERRITOIRES / 'regroupements_geographiques' / 'pat.xlsx'},
{'categorie_regroupement_communes': 'SCOT',
'fichier_source': CHEMIN_INPUT_DATA / DOSSIER_REFERENTIEL_TERRITOIRES / 'regroupements_geographiques' / 'scot.xlsx'}],
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment