Commit fa78c6e1 authored by Lionel's avatar Lionel
Browse files

2 traitements distincts pour gérer les sources territoires et les sources de...

2 traitements distincts pour gérer les sources territoires et les sources de données complémentaires associées aux territoires
parent a1a29410
......@@ -26,7 +26,9 @@ from crater.reglages import (
DOSSIER_PARCEL, DOSSIER_CRATER, DOSSIER_PRODUCTION_BESOINS, DOSSIER_RPG
)
from crater.surface_agricole_utile import collecteur_rpg, calculateur_surface_agricole_utile
from crater.territoires.calculateur_territoires import calculer_territoires, charger_referentiel_territoires
from crater.territoires.calculateur_territoires import calculer_referentiel_territoires, \
charger_referentiel_territoires_et_donnees_complementaires, charger_referentiel_territoires, \
calculer_donnees_complementaires_territoires
def lancer_calcul_surface_agricole_utile():
......@@ -61,13 +63,22 @@ def lancer_calcul_complet_referentiel_crater():
def lancer_calcul_territoires():
calculer_territoires(
calculer_referentiel_territoires(
CHEMIN_SOURCE_COMMUNES_ET_ARRONDISSEMENTS,
CHEMIN_SOURCE_MOUVEMENTS_COMMUNES,
CHEMIN_SOURCE_EPCIS,
CHEMIN_SOURCE_DEPARTEMENTS,
CHEMIN_SOURCE_REGIONS,
CHEMIN_SOURCE_CODES_POSTAUX,
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
# On recharge les dataframes des territoires a partir des fichiers calculés ci-dessus pour avoir systématiquement le même fonctionnement (erreurs d'arrondis possible pour les floats sinon)
territoires = charger_referentiel_territoires(CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES)
calculer_donnees_complementaires_territoires(
territoires,
CHEMIN_SOURCE_COMMUNES_ET_ARRONDISSEMENTS,
CHEMIN_SOURCE_MOUVEMENTS_COMMUNES,
CHEMIN_SOURCE_POPULATION_TOTALE,
CHEMIN_SOURCE_POPULATION_TOTALE_HISTORIQUE,
CHEMIN_OUTPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE / 'sau_par_commune_et_culture',
......@@ -76,8 +87,9 @@ def lancer_calcul_territoires():
)
def lancer_calcul_population_agricole():
referentiel_territoires = charger_referentiel_territoires(
referentiel_territoires = charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
......@@ -93,7 +105,7 @@ def lancer_calcul_population_agricole():
def lancer_calcul_politique_fonciere():
referentiel_territoires = charger_referentiel_territoires(
referentiel_territoires = charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
......@@ -109,7 +121,7 @@ def lancer_calcul_politique_fonciere():
def lancer_calcul_pratiques_agricoles():
referentiel_territoires = charger_referentiel_territoires(
referentiel_territoires = charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
......@@ -124,7 +136,7 @@ def lancer_calcul_pratiques_agricoles():
def lancer_calcul_production_besoins():
referentiel_territoires = charger_referentiel_territoires(
referentiel_territoires = charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
......
......@@ -45,23 +45,33 @@ def _generer_referentiel_territoires(sources: DictTerritoires) -> DictTerritoire
_ajouter_id_pays_aux_territoires(territoires)
return territoires
def _ajouter_donnees_complementaires_referentiel_territoires(territoires: DictTerritoires,
source_arrondissements: DataFrame,
source_mouvements_communes: DataFrame,
sources: DictTerritoires) -> DictTerritoires:
log.info("##### AJOUT DES DONNEES COMPLEMENTAIRES (population, sau,...) AUX TERRITOIRES #####")
_ajouter_sau(
territoires,
sources['sau'],
sources['mouvements_communes'],
source_mouvements_communes,
2019
)
_ajouter_population_totale(
territoires,
sources['arrondissements'],
source_arrondissements,
sources['population_totale'],
sources['mouvements_communes'],
source_mouvements_communes,
2019
)
_ajouter_population_totale_historique(
territoires,
sources['population_totale_historique'],
sources['mouvements_communes'],
source_mouvements_communes,
2017
)
_ajouter_id_territoire_parcel(
......@@ -99,36 +109,16 @@ def _exporter_referentiel_territoires(
log.info("##### EXPORT DES TERRITOIRES #####")
reinitialiser_dossier(chemin_dossier_output)
outils_territoires.exporter_fichiers_multiples(
outils_territoires.copier_en_supprimant_colonnes(
territoires,
['sau_ha',
'population_totale_2017',
'population_totale_2010',
'population_totale_1990',
'id_territoire_parcel']
),
chemin_dossier_output
)
outils_territoires.exporter_fichier_unique(
outils_territoires.copier_en_gardant_colonnes(
territoires,
['sau_ha',
'population_totale_2017',
'population_totale_2010',
'population_totale_1990',
'id_territoire_parcel']
),
chemin_dossier_output / "donnees.csv"
)
outils_territoires.exporter_fichiers_multiples(territoires, chemin_dossier_output)
territoires_assembles = (outils_territoires
.assembler_dict_territoires_en_df_territoires(territoires)
.loc[:,
['id_territoire', 'nom_territoire', 'categorie_territoire', 'codes_postaux', 'id_epci', 'id_departement', 'id_region', 'id_pays']
]
.rename(columns={'codes_postaux': 'codes_postaux_commune'})
)
['id_territoire', 'nom_territoire', 'categorie_territoire', 'codes_postaux', 'id_epci',
'id_departement', 'id_region', 'id_pays']
]
.rename(columns={'codes_postaux': 'codes_postaux_commune'})
)
# temporaire : pour fixer le bug d'affichage pycharm => affichage KO avec float avec NA de pandas...alors que ca marche avec NaN de numpy
# territoires_assembles.annee_dernier_mouvement = territoires_assembles.annee_dernier_mouvement.fillna(0)
......@@ -141,7 +131,6 @@ def _exporter_referentiel_territoires(
)
def _creer_base_de_donnees_pays() -> DataFrame:
pays = pd.DataFrame(
{'id_pays': [outils_territoires.ID_FRANCE], 'nom_pays': ['France']},
......@@ -160,28 +149,28 @@ def _ajouter_id_pays_aux_territoires(territoires: DictTerritoires) -> None:
def _ajouter_id_departement_et_region_aux_epcis(territoires: DictTerritoires) -> None:
nb_communes_par_epci_et_departement = (territoires['communes']
# .loc[(territoires['communes'].annee_dernier_mouvement.isna()) | (territoires['communes'].annee_dernier_mouvement >= 2020)]
.groupby(['id_epci', 'id_departement']).size()
.reset_index()
.rename(
columns={0: "nb_communes_par_epci_et_departement", "id_departement": "id_departement_pour_epci"})
)
# .loc[(territoires['communes'].annee_dernier_mouvement.isna()) | (territoires['communes'].annee_dernier_mouvement >= 2020)]
.groupby(['id_epci', 'id_departement']).size()
.reset_index()
.rename(
columns={0: "nb_communes_par_epci_et_departement", "id_departement": "id_departement_pour_epci"})
)
index_lignes_avec_max_nb_communes = (nb_communes_par_epci_et_departement
.reset_index()
.groupby(['id_epci'])
['nb_communes_par_epci_et_departement']
.idxmax())
.reset_index()
.groupby(['id_epci'])
['nb_communes_par_epci_et_departement']
.idxmax())
departement_appartenance_epci = (nb_communes_par_epci_et_departement
.loc[index_lignes_avec_max_nb_communes]
.rename(columns={'id_departement_pour_epci' : 'id_departement'} )
)
.loc[index_lignes_avec_max_nb_communes]
.rename(columns={'id_departement_pour_epci': 'id_departement'})
)
departement_appartenance_epci = (departement_appartenance_epci
.merge(territoires['departements'], how='left', on='id_departement')
.loc[:, ['id_epci', 'id_departement', 'id_region']])
.merge(territoires['departements'], how='left', on='id_departement')
.loc[:, ['id_epci', 'id_departement', 'id_region']])
territoires['epcis'] = territoires['epcis'].merge(departement_appartenance_epci, how='left',
on=['id_epci'])
on=['id_epci'])
def _ajouter_codes_postaux(territoires: DictTerritoires, arrondissements: DataFrame, codes_postaux: DataFrame) -> None:
......@@ -369,69 +358,105 @@ def _ajouter_id_commune(arrondissements: DataFrame, df: DataFrame):
return df
def charger_referentiel_territoires(dossier_territoires: Path) -> DictTerritoires:
log.info("##### CHARGEMENT DES TERRITOIRES #####")
def charger_referentiel_territoires_et_donnees_complementaires(dossier_territoires: Path) -> DictTerritoires:
referentiel_territoires = charger_referentiel_territoires(dossier_territoires)
log.info("##### CHARGEMENT DES DONNEES COMPLEMENTAIRES DES TERRITOIRES #####")
return outils_territoires.joindre_donnees(
outils_territoires.compiler_territoires(
chargeur_territoires.charger_communes(dossier_territoires / "communes.csv"),
chargeur_territoires.charger_epcis(dossier_territoires / "epcis.csv"),
chargeur_territoires.charger_departements(dossier_territoires / "departements.csv"),
chargeur_territoires.charger_regions(dossier_territoires / "regions.csv"),
chargeur_territoires.charger_pays(dossier_territoires / "pays.csv")
),
# TODO: Est ce que les données attachées directement aux territoires ne sont pas à considérées commes des données d'indicateurs ? Et à charger dans un autre module ?
# Cela permettrait de simplifier le code territoire
referentiel_territoires,
chargeur_territoires.charger_donnees(dossier_territoires / "donnees.csv")
)
def calculer_territoires(
def charger_referentiel_territoires(dossier_territoires: Path) -> DictTerritoires:
log.info("##### CHARGEMENT DES TERRITOIRES #####")
referentiel_territoires = outils_territoires.compiler_territoires(
chargeur_territoires.charger_communes(dossier_territoires / "communes.csv"),
chargeur_territoires.charger_epcis(dossier_territoires / "epcis.csv"),
chargeur_territoires.charger_departements(dossier_territoires / "departements.csv"),
chargeur_territoires.charger_regions(dossier_territoires / "regions.csv"),
chargeur_territoires.charger_pays(dossier_territoires / "pays.csv"))
return referentiel_territoires
def calculer_referentiel_territoires(
chemin_fichier_communes_et_arrondissements: Path,
chemin_fichier_mouvements_communes: Path,
chemin_fichier_epcis: Path,
chemin_fichier_departements: Path,
chemin_fichier_regions: Path,
chemin_fichier_codes_postaux: Path,
chemin_dossier_output: Path
) -> None:
sources_territoires = _charger_sources_territoires(
chemin_fichier_communes_et_arrondissements,
chemin_fichier_mouvements_communes,
chemin_fichier_epcis,
chemin_fichier_departements,
chemin_fichier_regions,
chemin_fichier_codes_postaux,
chemin_fichier_population_totale,
chemin_fichier_population_totale_historique,
chemin_fichiers_sau,
chemin_fichier_territoires_parcel,
chemin_fichier_codes_postaux
)
territoires = _generer_referentiel_territoires(
sources_territoires
)
_exporter_referentiel_territoires(
territoires,
chemin_dossier_output
)
def calculer_donnees_complementaires_territoires(
territoires: DictTerritoires,
chemin_fichier_communes_et_arrondissements: Path,
chemin_fichier_mouvements_communes: Path,
chemin_fichier_population_totale: Path,
chemin_fichier_population_totale_historique: Path,
chemin_fichiers_sau: Path,
chemin_fichier_territoires_parcel: Path,
chemin_dossier_output: Path
) -> None:
sources = _charger_sources(
# TODO : supprimer l'utilisation du fichier des mouvements communs pour utiliser les données dans le DF territoires
# TODO : Voir si on peut pas faire pareil avec les arrondissements
sources_territoires_donnees_complementaires = _charger_sources_territoires_donnees_complementaires(
chemin_fichier_communes_et_arrondissements,
chemin_fichier_mouvements_communes,
chemin_fichier_epcis,
chemin_fichier_departements,
chemin_fichier_regions,
chemin_fichier_codes_postaux,
chemin_fichier_population_totale,
chemin_fichier_population_totale_historique,
chemin_fichiers_sau,
chemin_fichier_territoires_parcel
)
territoires = _generer_referentiel_territoires(
sources
)
_exporter_referentiel_territoires(
territoires_enrichi = _ajouter_donnees_complementaires_referentiel_territoires(
territoires,
chemin_dossier_output
sources_territoires_donnees_complementaires['arrondissements'],
sources_territoires_donnees_complementaires['mouvements_communes'],
sources_territoires_donnees_complementaires
)
outils_territoires.exporter_fichier_unique(
outils_territoires.copier_en_gardant_colonnes(
territoires_enrichi,
['sau_ha',
'population_totale_2017',
'population_totale_2010',
'population_totale_1990',
'id_territoire_parcel']
),
chemin_dossier_output / "donnees.csv"
)
def _charger_sources(
def _charger_sources_territoires(
chemin_fichier_communes_et_arrondissements: Path,
chemin_fichier_mouvements_communes: Path,
chemin_fichier_epcis: Path,
chemin_fichier_departements: Path,
chemin_fichier_regions: Path,
chemin_fichier_codes_postaux: Path,
chemin_fichier_population_totale: Path,
chemin_fichier_population_totale_historique: Path,
chemin_fichiers_sau: Path,
chemin_fichier_territoires_parcel: Path
chemin_fichier_codes_postaux: Path
) -> DictTerritoires:
log.info("##### CHARGEMEMENT DES DONNEES SOURCES DE TERRITOIRES #####")
......@@ -443,14 +468,6 @@ def _charger_sources(
regions = chargeur_regions.charger(chemin_fichier_regions)
codes_postaux = chargeur_codes_postaux.charger(chemin_fichier_codes_postaux)
sau = chargeur_sau_par_commune_et_culture.charger(chemin_fichiers_sau)
population_totale = chargeur_population_totale.charger(chemin_fichier_population_totale)
population_totale_historique = chargeur_population_totale_historique.charger(
chemin_fichier_population_totale_historique)
territoires_parcel = chargeur_territoires_parcel.charger(chemin_fichier_territoires_parcel)
chargeur_communes.traduire_code_insee_vers_id_crater(communes)
chargeur_arrondissements.traduire_code_insee_vers_id_crater(arrondissements)
chargeur_mouvements_communes.traduire_code_insee_vers_id_crater(mouvements_communes)
......@@ -459,9 +476,6 @@ def _charger_sources(
chargeur_regions.traduire_code_insee_vers_id_crater(regions)
chargeur_codes_postaux.traduire_code_insee_vers_id_crater(codes_postaux)
chargeur_population_totale.traduire_code_insee_vers_id_crater(population_totale)
chargeur_population_totale_historique.traduire_code_insee_vers_id_crater(population_totale_historique)
return {
'communes': communes,
'mouvements_communes': mouvements_communes,
......@@ -470,9 +484,41 @@ def _charger_sources(
'regions': regions,
'arrondissements': arrondissements,
'codes_postaux': codes_postaux,
}
def _charger_sources_territoires_donnees_complementaires(
chemin_fichier_communes_et_arrondissements: Path,
chemin_fichier_mouvements_communes: Path,
chemin_fichier_population_totale: Path,
chemin_fichier_population_totale_historique: Path,
chemin_fichiers_sau: Path,
chemin_fichier_territoires_parcel: Path
) -> DictTerritoires:
log.info(
"##### CHARGEMEMENT DES DONNEES SOURCES COMPLEMENTAIRES RATTACHEES AUX TERRITOIRES (population, sau,...) #####")
arrondissements = chargeur_arrondissements.charger(chemin_fichier_communes_et_arrondissements)
mouvements_communes = chargeur_mouvements_communes.charger_mouvements(chemin_fichier_mouvements_communes)
chargeur_arrondissements.traduire_code_insee_vers_id_crater(arrondissements)
chargeur_mouvements_communes.traduire_code_insee_vers_id_crater(mouvements_communes)
sau = chargeur_sau_par_commune_et_culture.charger(chemin_fichiers_sau)
population_totale = chargeur_population_totale.charger(chemin_fichier_population_totale)
population_totale_historique = chargeur_population_totale_historique.charger(
chemin_fichier_population_totale_historique)
territoires_parcel = chargeur_territoires_parcel.charger(chemin_fichier_territoires_parcel)
chargeur_population_totale.traduire_code_insee_vers_id_crater(population_totale)
chargeur_population_totale_historique.traduire_code_insee_vers_id_crater(population_totale_historique)
return {
'mouvements_communes': mouvements_communes,
'arrondissements': arrondissements,
'population_totale': population_totale,
'population_totale_historique': population_totale_historique,
'sau': sau,
'territoires_parcel': territoires_parcel
}
......@@ -18,7 +18,7 @@ class TestPolitiqueFonciere(unittest.TestCase):
def test_politique_fonciere_cas_nominal(self):
# given
reinitialiser_dossier(CHEMIN_OUTPUT_DATA / DOSSIER_POLITIQUE_FONCIERE)
territoires = calculateur_territoire.charger_referentiel_territoires(
territoires = calculateur_territoire.charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_EXPECTED_DATA / DOSSIER_TERRITOIRES
)
# when
......
......@@ -18,7 +18,7 @@ class TestPopulationAgricole(unittest.TestCase):
def test_population_agricole_cas_nominal(self):
# given
reinitialiser_dossier(CHEMIN_OUTPUT_DATA / DOSSIER_POPULATION_AGRICOLE)
territoires = calculateur_territoires.charger_referentiel_territoires(
territoires = calculateur_territoires.charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_EXPECTED_DATA / DOSSIER_TERRITOIRES
)
# when
......
......@@ -18,7 +18,7 @@ class TestPratiquesAgricoles(unittest.TestCase):
def test_pratiques_agricoles_cas_nominal(self):
# given
reinitialiser_dossier(CHEMIN_OUTPUT_DATA / DOSSIER_PRATIQUES_AGRICOLES)
referentiel_territoires = calculateur_territoires.charger_referentiel_territoires(
referentiel_territoires = calculateur_territoires.charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_EXPECTED_DATA / DOSSIER_TERRITOIRES
)
# when
......
......@@ -9,7 +9,7 @@ from crater.production_besoins.calculateur_production_besoins import calculer_ax
from crater.production_besoins.production import calculer_production
from crater.reglages import DOSSIER_PRODUCTION_BESOINS, DOSSIER_TERRITOIRES, DOSSIER_PARCEL, \
DOSSIER_SURFACE_AGRICOLE_UTILE
from crater.territoires.calculateur_territoires import charger_referentiel_territoires
from crater.territoires.calculateur_territoires import charger_referentiel_territoires_et_donnees_complementaires
from tests.test_outils import CHEMIN_OUTPUT_DATA, CHEMIN_EXPECTED_DATA, CHEMIN_INPUT_DATA, \
assert_csv_files_are_equals
......@@ -21,7 +21,7 @@ class TestProductionBesoins(unittest.TestCase):
reinitialiser_dossier(CHEMIN_OUTPUT_DATA / DOSSIER_PRODUCTION_BESOINS)
def test_calculer_besoins(self):
territoires = charger_referentiel_territoires(
territoires = charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_EXPECTED_DATA / DOSSIER_TERRITOIRES
)
territoires_initial = copy.deepcopy(territoires)
......@@ -41,7 +41,7 @@ class TestProductionBesoins(unittest.TestCase):
pandas.testing.assert_frame_equal(territoires_initial['communes'], territoires['communes'])
def test_calculer_production(self):
territoires = charger_referentiel_territoires(
territoires = charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_EXPECTED_DATA / DOSSIER_TERRITOIRES
)
territoires_initial = copy.deepcopy(territoires)
......@@ -61,7 +61,7 @@ class TestProductionBesoins(unittest.TestCase):
pandas.testing.assert_frame_equal(territoires_initial['communes'], territoires['communes'])
def test_calculer_production_besoins(self):
territoires = charger_referentiel_territoires(
territoires = charger_referentiel_territoires_et_donnees_complementaires(
CHEMIN_EXPECTED_DATA / DOSSIER_TERRITOIRES
)
calculer_axe_production_besoins(
......
......@@ -2,6 +2,8 @@ import unittest
from crater.reglages import DOSSIER_TERRITOIRES, DOSSIER_SURFACE_AGRICOLE_UTILE, DOSSIER_PARCEL
from crater.territoires import calculateur_territoires
from crater.territoires.calculateur_territoires import charger_referentiel_territoires, \
calculer_donnees_complementaires_territoires
from tests.test_outils import assert_list_of_csv_files_are_equals, \
CHEMIN_INPUT_DATA, CHEMIN_OUTPUT_DATA, CHEMIN_EXPECTED_DATA
......@@ -9,19 +11,30 @@ from tests.test_outils import assert_list_of_csv_files_are_equals, \
class TestTerritoires(unittest.TestCase):
def test_generation_referentiel_territoires_csv_a_partir_sources(self):
calculateur_territoires.calculer_territoires(
calculateur_territoires.calculer_referentiel_territoires(
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'communes_et_arrondissements.xlsx',
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'table_passage_communes.xlsx',
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'epcis.xlsx',
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'departements.csv',
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'regions.csv',
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'codes_postaux.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
# On recharge les dataframes des territoires a partir des fichiers calculés ci-dessus pour avoir systématiquement le même fonctionnement (erreurs d'arrondis possible pour les floats sinon)
territoires = charger_referentiel_territoires(CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES)
calculer_donnees_complementaires_territoires(
territoires,
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'communes_et_arrondissements.xlsx',
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'table_passage_communes.xlsx',
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'population_totale_2017.csv',
CHEMIN_INPUT_DATA / DOSSIER_TERRITOIRES / 'population_totale_historique_2015.xlsx',
CHEMIN_INPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE / 'sau_par_commune_et_culture',
CHEMIN_INPUT_DATA / DOSSIER_PARCEL / 'correspondance_territoires_parcel_crater.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
assert_list_of_csv_files_are_equals(
CHEMIN_EXPECTED_DATA / DOSSIER_TERRITOIRES,
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES,
......
Supports Markdown
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