Commit d2736f5a authored by Benjam's avatar Benjam Committed by Lionel
Browse files

Module de calcul des superficies sur base de l'OSM pour ne pas dépendre des...

Module de calcul des superficies sur base de l'OSM pour ne pas dépendre des donnée CEREMA + ajustement module de vérification cohérence réferentiel et geometries communes + modification architecture lancement crater_data + independance des modules de test
parent 6b8c6afd
......@@ -16,7 +16,7 @@ from crater.production_besoins.calculateur_production_besoins import calculer_ax
from crater.reglages import (
DOSSIER_CONFIG,
CHEMIN_CRATER_DATA_SOURCES,
CHEMIN_SOURCE_COMMUNES_ET_ARRONDISSEMENTS, CHEMIN_SOURCE_COMMUNES_SIG, CHEMIN_SOURCE_MOUVEMENTS_COMMUNES,
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_POPULATION_TOTALE, CHEMIN_SOURCE_POPULATION_TOTALE_HISTORIQUE,
CHEMIN_SOURCE_POPULATION_AGRICOLE,
......@@ -50,52 +50,58 @@ def loguer_duree_etapes():
log.info("Temps d'éxecution traitement " + e['nom_etape'] + " = " + duree_etape)
def lancer_calcul_surface_agricole_utile(nombre_traitements_paralleles: int):
def lancer_etape_crater(etape: Callable):
debut = time.time()
reinitialiser_dossier(CHEMIN_OUTPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE)
log.info(f"#### DEBUT DE L'ETAPE {etape.__name__} ####")
etape()
log.info(f"#### FIN DE L'ETAPE {etape.__name__} ####")
return {'nom_etape': etape.__name__, 'duree': (time.time() - debut)}
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,
DOSSIER_CONFIG / "regroupements_geographiques",
CHEMIN_OUTPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE
)
referentiel_territoires = charger_referentiel_territoires(
CHEMIN_OUTPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE
)
communes_sig = calculateur_surface_agricole_utile.charger_communes_sig(
CHEMIN_SOURCE_COMMUNES_SIG,
referentiel_territoires
def lancer_telechargement_parcel_assiette_actuelle():
collecteur_besoins_api_parcel.collecter_donnees_besoins_parcel(
ID_ASSIETTE_ACTUELLE,
DOSSIER_CONFIG / DOSSIER_PARCEL / 'correspondance_territoires_parcel_crater.csv',
DOSSIER_CONFIG / DOSSIER_PARCEL / 'parcel_produits_et_categories_202008.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_PARCEL /
'reponse_api_parcel_besoins_sau_par_produits_assiette_actuelle.csv'
)
calculateur_surface_agricole_utile.calculer_surface_agricole_utile_par_commune_et_culture(
2017,
referentiel_territoires,
communes_sig,
CHEMIN_CRATER_DATA_SOURCES / DOSSIER_IGN,
NOMS_FICHIERS_RPG,
CHEMIN_OUTPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE,
nombre_traitements_paralleles
def lancer_telechargement_parcel_assiette_25p():
collecteur_besoins_api_parcel.collecter_donnees_besoins_parcel(
ID_ASSIETTE_MOINS_25_POURCENT,
DOSSIER_CONFIG / DOSSIER_PARCEL / 'correspondance_territoires_parcel_crater.csv',
DOSSIER_CONFIG / DOSSIER_PARCEL / 'parcel_produits_et_categories_202008.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_PARCEL /
'reponse_api_parcel_besoins_sau_par_produits_assiette_moins_25p.csv'
)
stocker_duree_etape('CALCUL_SURFACES_AGRICOLES_UTILES', time.time() - debut)
def lancer_telechargement_parcel_assiette_50p():
collecteur_besoins_api_parcel.collecter_donnees_besoins_parcel(
ID_ASSIETTE_MOINS_50_POURCENT,
DOSSIER_CONFIG / DOSSIER_PARCEL / 'correspondance_territoires_parcel_crater.csv',
DOSSIER_CONFIG / DOSSIER_PARCEL / 'parcel_produits_et_categories_202008.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_PARCEL /
'reponse_api_parcel_besoins_sau_par_produits_assiette_moins_50p.csv'
)
def lancer_etape_crater(etape: Callable):
debut = time.time()
log.info(f"#### DEBUT DE L'ETAPE {etape.__name__} ####")
etape()
log.info(f"#### FIN DE L'ETAPE {etape.__name__} ####")
return {'nom_etape': etape.__name__, 'duree': (time.time() - debut)}
def lancer_telechargement_rpg():
collecteur_rpg.telecharger_rpg_toutes_les_regions(
URL_SOURCE_RPG,
NOMS_FICHIERS_RPG,
2017,
CHEMIN_CRATER_DATA_SOURCES / DOSSIER_IGN
)
def lancer_calcul_complet_traitement_crater(nombre_traitements_paralleles: int):
lancer_calcul_territoires()
def lancer_calcul_traitement_crater(nombre_traitements_paralleles: int, option: str):
lancer_calcul_referentiel_territoires()
if option == 'complet':
lancer_calcul_surface_agricole_utile()
lancer_calcul_donnees_territoires()
etapes_parallelisables = [lancer_calcul_population_agricole, lancer_calcul_politique_fonciere,
lancer_calcul_pratiques_agricoles, lancer_calcul_production_besoins]
......@@ -105,9 +111,9 @@ def lancer_calcul_complet_traitement_crater(nombre_traitements_paralleles: int):
duree_etapes.extend(duree_etapes_pool)
lancer_calcul_cartes()
def lancer_calcul_territoires():
def lancer_calcul_referentiel_territoires():
debut = time.time()
reinitialiser_dossier(CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES)
......@@ -122,12 +128,41 @@ def lancer_calcul_territoires():
DOSSIER_CONFIG / "regroupements_geographiques",
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)
referentiel_territoires = charger_referentiel_territoires(CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES)
stocker_duree_etape('CALCUL_REFERENTIEL_TERRITOIRES', time.time() - debut)
def lancer_calcul_surface_agricole_utile(nombre_traitements_paralleles: int):
debut = time.time()
reinitialiser_dossier(CHEMIN_OUTPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE)
referentiel_territoires = charger_referentiel_territoires(
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
calculateur_surface_agricole_utile.calculer_surface_agricole_utile_par_commune_et_culture(
2017,
referentiel_territoires,
CHEMIN_DOSSIER_SOURCE_GEOMETRIES_COMMUNES,
CHEMIN_CRATER_DATA_SOURCES / DOSSIER_IGN,
NOMS_FICHIERS_RPG,
CHEMIN_OUTPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE,
nombre_traitements_paralleles
)
stocker_duree_etape('CALCUL_SURFACES_AGRICOLES_UTILES', time.time() - debut)
def lancer_calcul_donnees_territoires():
debut = time.time()
referentiel_territoires = charger_referentiel_territoires(
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
calculer_donnees_territoires(
referentiel_territoires,
CHEMIN_DOSSIER_SOURCE_GEOMETRIES_COMMUNES,
CHEMIN_SOURCE_POPULATION_TOTALE,
CHEMIN_SOURCE_POPULATION_TOTALE_HISTORIQUE,
CHEMIN_OUTPUT_DATA / DOSSIER_SURFACE_AGRICOLE_UTILE / 'sau_par_commune_et_culture',
......@@ -136,7 +171,7 @@ def lancer_calcul_territoires():
CHEMIN_OUTPUT_DATA / DOSSIER_TERRITOIRES
)
stocker_duree_etape('CALCUL_REFERENTIEL_TERRITOIRES', time.time() - debut)
stocker_duree_etape('CALCUL_DONNEES_TERRITOIRES', time.time() - debut)
def lancer_calcul_population_agricole():
......@@ -208,7 +243,7 @@ def lancer_calcul_cartes():
calculer_cartes(
CHEMIN_CRATER_DATA_SOURCES / 'france_geojson' / 'regions.geojson',
CHEMIN_CRATER_DATA_SOURCES / 'france_geojson' / 'departements.geojson',
CHEMIN_CRATER_DATA_SOURCES / 'banatic' / 'epci_sig' / '2020' / 'Epci2020_region.shp',
CHEMIN_CRATER_DATA_SOURCES / 'banatic' / 'geometries_epcis' / '2020' / 'Epci2020_region.shp',
CHEMIN_OUTPUT_DATA / DOSSIER_PRODUCTION_BESOINS / 'production_besoins.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_PRATIQUES_AGRICOLES / 'pratiques_agricoles.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_POPULATION_AGRICOLE / 'population_agricole.csv',
......@@ -223,17 +258,19 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser(usage='%(prog)s [OPTIONS] ETAPE_CALCUL\n'
+ 'Permet de lancer une étape ou un groupe d\'étapes de traitements de crater-data\n'
+ "Valeurs possible pour ETAPE_CALCUL :\n"
+ "\tparcel-besoins-assiette-actuelle\tgénérer le fichier des besoins en SAU à partir de l'api PARCEL, pour l'assiette actuelle\n"
+ "\tparcel-besoins-assiette-25p\t\tgénérer le fichier des besoins en SAU à partir de l'api PARCEL, pour une assiette avec -25 pourcent de produit de l'élevage\n"
+ "\tparcel-besoins-assiette-50p\t\tgénérer le fichier des besoins en SAU à partir de l'api PARCEL, pour une assiette avec -50 poucent de produit de l'élevage\n"
+ "\tsau-telecharger-rpg\t\t\ttélécharger les fichiers régionales du RPG\n"
+ "\tsau-calculer-surfaces\t\t\tgénérer les fichiers résultat crater-data des surfaces agricoles utiles\n"
+ "\ttelecharger-parcel-besoins-assiette-actuelle\tgénérer le fichier des besoins en SAU à partir de l'api PARCEL, pour l'assiette actuelle\n"
+ "\ttelecharger-parcel-besoins-assiette-25p\t\tgénérer le fichier des besoins en SAU à partir de l'api PARCEL, pour une assiette avec -25 pourcent de produit de l'élevage\n"
+ "\ttelecharger-parcel-besoins-assiette-50p\t\tgénérer le fichier des besoins en SAU à partir de l'api PARCEL, pour une assiette avec -50 poucent de produit de l'élevage\n"
+ "\ttelecharger-rpg\t\t\ttélécharger les fichiers régionales du RPG\n"
+ "\tcrater-complet\t\t\t\tgénérer l'ensemble des fichiers résultat crater-data. Exécute toutes les étapes carter-* dans l'ordre\n"
+ "\tcrater-territoires\t\t\tgénérer les fichiers résultat crater-data, pour les territoires\n"
+ "\tcrater-population-agricole\t\tgénérer les fichiers résultat crater-data, pour l'axe population agricole\n"
+ "\tcrater-politique-fonciere\t\tgénérer les fichiers résultat crater-data, pour l'axe politique foncière\n"
+ "\tcrater-pratiques-agricoles\t\tgénérer les fichiers résultat crater-data, pour l'axe pratiques agricoles\n"
+ "\tcrater-production-besoins\t\tgénérer les fichiers résultat crater-data, pour l'axe production-besoins\n"
+ "\tcrater-incomplet-rapide\t\t\t\tgénérer certains fichiers résultat crater-data. Exécute uniquement une partie des étapes crater-* dans l'ordre\n"
+ "\tcrater-referentiel-territoires\t\t\tgénérer le referentiel des territoires\n"
+ "\tcrater-calculer-sau\t\t\tgénérer les surfaces agricoles utiles\n"
+ "\tcrater-donnees-territoires\t\t\tgénérer les données de territoires\n"
+ "\tcrater-population-agricole\t\tgénérer l'axe population agricole\n"
+ "\tcrater-politique-fonciere\t\tgénérer l'axe politique foncière\n"
+ "\tcrater-pratiques-agricoles\t\tgénérer l'axe pratiques agricoles\n"
+ "\tcrater-production-besoins\t\tgénérer l'axe production-besoins\n"
+ "\tcrater-cartes\t\t\t\tgénérer les fichiers geojson contenant les contours géographiques des territoires et certains indicateurs\n"
+ "\n"
+ "Valeurs possible pour OPTIONS :\n"
......@@ -242,13 +279,15 @@ if __name__ == '__main__':
)
parser.add_argument("ETAPE_CALCUL",
help="Nom de l'étape à exécuter",
choices=['parcel-besoins-assiette-actuelle',
'parcel-besoins-assiette-25p',
'parcel-besoins-assiette-50p',
'sau-telecharger-rpg',
'sau-calculer-surfaces',
choices=['telecharger-parcel-besoins-assiette-actuelle',
'telecharger-parcel-besoins-assiette-25p',
'telecharger-parcel-besoins-assiette-50p',
'telecharger-rpg',
'crater-complet',
'crater-territoires',
'crater-incomplet-rapide',
'crater-referentiel-territoires',
'crater-calculer-sau',
'crater-donnees-territoires',
'crater-pratiques-agricoles',
'crater-politique-fonciere',
'crater-production-besoins',
......@@ -261,50 +300,36 @@ if __name__ == '__main__':
nombre_traitements_paralleles = args.p
if (args.ETAPE_CALCUL == 'parcel-besoins-assiette-actuelle'):
if (args.ETAPE_CALCUL == 'telecharger-parcel-besoins-assiette-actuelle'):
log.info(
"Génération du fichier des besoins SAUs pour les territoires à partir de l'API PARCEL, assiette actuelle")
collecteur_besoins_api_parcel.collecter_donnees_besoins_parcel(
ID_ASSIETTE_ACTUELLE,
DOSSIER_CONFIG / DOSSIER_PARCEL / 'correspondance_territoires_parcel_crater.csv',
DOSSIER_CONFIG / DOSSIER_PARCEL / 'parcel_produits_et_categories_202008.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_PARCEL / 'reponse_api_parcel_besoins_sau_par_produits_assiette_actuelle.csv'
)
elif (args.ETAPE_CALCUL == 'parcel-besoins-assiette-25p'):
"Téléchargement et génération du fichier des besoins SAUs pour les territoires à partir de l'API PARCEL, assiette actuelle")
lancer_telechargement_parcel_assiette_actuelle()
elif (args.ETAPE_CALCUL == 'telecharger-parcel-besoins-assiette-25p'):
log.info(
"Génération du fichier des besoins SAUs pour les territoires à partir de l'API PARCEL, assiette -25% viande")
collecteur_besoins_api_parcel.collecter_donnees_besoins_parcel(
ID_ASSIETTE_MOINS_25_POURCENT,
DOSSIER_CONFIG / DOSSIER_PARCEL / 'correspondance_territoires_parcel_crater.csv',
DOSSIER_CONFIG / DOSSIER_PARCEL / 'parcel_produits_et_categories_202008.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_PARCEL / 'reponse_api_parcel_besoins_sau_par_produits_assiette_moins_25p.csv'
)
elif (args.ETAPE_CALCUL == 'parcel-besoins-assiette-50p'):
"Téléchargement et génération du fichier des besoins SAUs pour les territoires à partir de l'API PARCEL, assiette -25% viande")
lancer_telechargement_parcel_assiette_25p()
elif (args.ETAPE_CALCUL == 'telecharger-parcel-besoins-assiette-50p'):
log.info(
"Génération du fichier des besoins SAUs pour les territoires à partir de l'API PARCEL, assiette -50% viande")
collecteur_besoins_api_parcel.collecter_donnees_besoins_parcel(
ID_ASSIETTE_MOINS_50_POURCENT,
DOSSIER_CONFIG / DOSSIER_PARCEL / 'correspondance_territoires_parcel_crater.csv',
DOSSIER_CONFIG / DOSSIER_PARCEL / 'parcel_produits_et_categories_202008.csv',
CHEMIN_OUTPUT_DATA / DOSSIER_PARCEL / 'reponse_api_parcel_besoins_sau_par_produits_assiette_moins_50p.csv'
)
elif (args.ETAPE_CALCUL == 'sau-telecharger-rpg'):
log.info("Téléchargmeent des fichiers source RPG")
collecteur_rpg.telecharger_rpg_toutes_les_regions(
URL_SOURCE_RPG,
NOMS_FICHIERS_RPG,
2017,
CHEMIN_CRATER_DATA_SOURCES / DOSSIER_IGN
)
elif (args.ETAPE_CALCUL == 'sau-calculer-surfaces'):
"Téléchargement et génération du fichier des besoins SAUs pour les territoires à partir de l'API PARCEL, assiette -50% viande")
lancer_telechargement_parcel_assiette_50p()
elif (args.ETAPE_CALCUL == 'telecharger-rpg'):
log.info("Téléchargement des fichiers source RPG")
lancer_telechargement_rpg()
elif (args.ETAPE_CALCUL == 'crater-complet'):
log.info("Génération de tous les fichiers résultats CRATER")
lancer_calcul_traitement_crater(nombre_traitements_paralleles, 'complet')
elif (args.ETAPE_CALCUL == 'crater-incomplet-rapide'):
log.info("Génération de certains fichiers résultats CRATER")
lancer_calcul_traitement_crater(nombre_traitements_paralleles, 'rapide')
elif (args.ETAPE_CALCUL == 'crater-referentiel-territoires'):
log.info("Génération des fichiers résultats CRATER pour le réferentiel de territoires")
lancer_calcul_referentiel_territoires()
elif (args.ETAPE_CALCUL == 'crater-calculer-sau'):
log.info("Génération des fichiers résultats CRATER des surfaces agricoles utiles")
lancer_calcul_surface_agricole_utile(nombre_traitements_paralleles)
elif (args.ETAPE_CALCUL == 'crater-complet'):
log.info("Génération des fichiers résultats CRATER")
lancer_calcul_complet_traitement_crater(nombre_traitements_paralleles)
elif (args.ETAPE_CALCUL == 'crater-territoires'):
log.info("Génération des fichiers résultats CRATER pour les territoires")
lancer_calcul_territoires()
elif (args.ETAPE_CALCUL == 'crater-donnees-territoires'):
log.info("Génération des fichiers résultats CRATER pour les données de territoires")
lancer_calcul_donnees_territoires()
elif (args.ETAPE_CALCUL == 'crater-production-besoins'):
log.info("Génération des fichiers résultats CRATER pour l'axe production/besoins")
lancer_calcul_production_besoins()
......
......@@ -40,7 +40,7 @@ def _calculer_donnees_politique_fonciere(
territoires: DataFrame,
sources_politique_fonciere : DictDataFrames
) -> DataFrame:
colonnes = ['nom_territoire', 'categorie_territoire'] + IDS_CATEGORIES_TERRITOIRES_SUPRACOMMUNAUX + ['annee_dernier_mouvement_commune', 'sau_productive_ha', 'population_totale_2017']
colonnes = ['nom_territoire', 'categorie_territoire'] + IDS_CATEGORIES_TERRITOIRES_SUPRACOMMUNAUX + ['annee_dernier_mouvement_commune', 'superficie_ha', 'sau_productive_ha', 'population_totale_2017']
donnees_politique_fonciere = territoires[colonnes]
donnees_artificialisation = sources_politique_fonciere['artificialisation'].rename(
......@@ -76,10 +76,6 @@ def _calculer_donnees_politique_fonciere(
'evolution_menages_emplois_2011_2016',
type='Int64'
)
donnees_politique_fonciere = outils_territoires.ajouter_donnees_supracommunales_par_somme_donnees_communales(
donnees_politique_fonciere,
'superficie_ha'
)
donnees_politique_fonciere['artificialisation_2011_2016_sur_superficie_pourcent'] = \
donnees_politique_fonciere['artificialisation_2011_2016_ha'] / \
......
......@@ -99,17 +99,14 @@ def charger(chemin_fichier):
'idcom': 'id_commune',
'naf11art16': 'artificialisation_2011_2016_ha',
'men1116': 'evolution_menages_2011_2016',
'emp1116': 'evolution_emplois_2011_2016',
'surfcom18': 'superficie_ha'
'emp1116': 'evolution_emplois_2011_2016'
},
errors='raise'
).reindex(
columns=['id_commune',
'artificialisation_2011_2016_ha',
'evolution_menages_2011_2016',
'evolution_emplois_2011_2016',
'superficie_ha'
'evolution_emplois_2011_2016'
]
).loc[
lambda df: ~df['id_commune'].astype(str).str[0:2].isin(["97", "98"])
]
)
......@@ -6,9 +6,9 @@ CHEMIN_SOURCE_COMMUNES_ET_ARRONDISSEMENTS = Path(
CHEMIN_CRATER_DATA_SOURCES /
"insee/geographie/communes/2020/table-appartenance-geo-communes-20.xlsx"
)
CHEMIN_SOURCE_COMMUNES_SIG = Path(
CHEMIN_DOSSIER_SOURCE_GEOMETRIES_COMMUNES = Path(
CHEMIN_CRATER_DATA_SOURCES /
"open_street_map/communes_sig/2020/communes-20200101-shp/communes-20200101.shp"
"open_street_map/geometries_communes/2020/communes-20200101"
)
CHEMIN_SOURCE_EPCIS = Path(
CHEMIN_CRATER_DATA_SOURCES /
......@@ -64,8 +64,9 @@ CHEMIN_OUTPUT_DATA = Path("../crater-data-resultats/data")
DOSSIER_RPG = Path("rpg")
DOSSIER_PARCEL = Path("parcel")
DOSSIER_SURFACE_AGRICOLE_UTILE = Path("surface_agricole_utile")
DOSSIER_SOURCES_TERRITOIRES = Path("crater/sources_territoires")
DOSSIER_TERRITOIRES = Path("crater/territoires")
DOSSIER_REFERENTIEL_TERRITOIRES = Path("crater/referentiel_territoires")
DOSSIER_DONNEES_TERRITOIRES = Path("crater/donnees_territoires")
DOSSIER_POPULATION_AGRICOLE = Path("crater/population_agricole")
DOSSIER_POLITIQUE_FONCIERE = Path("crater/politique_fonciere")
DOSSIER_PRATIQUES_AGRICOLES = Path("crater/pratiques_agricoles")
......
......@@ -7,16 +7,16 @@ from pandas import DataFrame
import geopandas as gpd
import crater.surface_agricole_utile.chargeur_rpg as chargeur_rpg
import crater.surface_agricole_utile.chargeur_communes as chargeur_communes
from crater.territoires.chargeur_geometries_communes import charger_geometries_communes
import crater.territoires.outils as outils_territoires
from crater.crater_logger import log, chronometre
from crater.outils import reinitialiser_dossier
import crater.territoires.outils as outils_territoires
def calculer_surface_agricole_utile_par_commune_et_culture(
annee_rpg: int,
referentiel_territoires: pd.DataFrame,
communes_sig: gpd.GeoDataFrame,
chemin_fichiers_geometries_communes: Path,
dossier_rpg: Path,
noms_fichiers_rpg: List[str],
chemin_dossier_output: Path,
......@@ -24,9 +24,11 @@ def calculer_surface_agricole_utile_par_commune_et_culture(
) -> None:
log.info("##### CALCUL SURFACES AGRICOLES PAR COMMUNE ET CULTURE #####")
# NB: les fichiers RPG par région ne sont pas exclusifs (une parcelle à la frontière de 2 régions, peut se trouver
# dans les fichiers des 2 régions
# NB: les fichiers RPG par région ne sont pas exclusifs (une parcelle à la frontière de 2 régions peut se trouver
# dans les fichiers des 2 régions)
geometries_communes = _importer_communes(referentiel_territoires, chemin_fichiers_geometries_communes)
reinitialiser_dossier(chemin_dossier_output / 'sau_par_commune_et_culture')
ids_regions = referentiel_territoires.reset_index(
......@@ -38,7 +40,7 @@ def calculer_surface_agricole_utile_par_commune_et_culture(
for id_region in ids_regions:
_calculer_surface_agricole_utile_par_region(
annee_rpg,
communes_sig,
geometries_communes,
dossier_rpg,
noms_fichiers_rpg,
chemin_dossier_output,
......@@ -48,7 +50,7 @@ def calculer_surface_agricole_utile_par_commune_et_culture(
partial_calculer_surface_agricole_utile_par_region = partial(
_calculer_surface_agricole_utile_par_region,
annee_rpg,
communes_sig,
geometries_communes,
dossier_rpg,
noms_fichiers_rpg,
chemin_dossier_output
......@@ -58,22 +60,42 @@ def calculer_surface_agricole_utile_par_commune_et_culture(
pool.map(partial_calculer_surface_agricole_utile_par_region, ids_regions)
def _importer_communes(
referentiel_territoires: DataFrame,
chemin_fichiers_geometries_communes: Path
) -> gpd.GeoDataFrame:
geometries_communes = charger_geometries_communes(chemin_fichiers_geometries_communes)
outils_territoires.verifier_coherence_referentiel_avec_geometries_communes(
referentiel_territoires,
geometries_communes
)
geometries_communes = pd.merge(
geometries_communes,
referentiel_territoires[['id_region']],
left_on='id_commune',
right_on='id_territoire'
)
return geometries_communes
def _calculer_surface_agricole_utile_par_region(
annee_rpg: int,
communes_sig: gpd.GeoDataFrame,
geometries_communes: gpd.GeoDataFrame,
dossier_rpg: Path,
noms_fichiers_rpg: List[str],
chemin_dossier_output: Path,
id_region: str
):
rpg = chargeur_rpg.charger_rpg_shp(
rpg = chargeur_rpg.charger_rpg(
dossier_rpg / str(annee_rpg) / noms_fichiers_rpg[annee_rpg][id_region]
)
log.info('Intersection RPG - Communes de la région ' + str(id_region))
intersection = _intersecter_rpg_communes(
communes_sig.query('id_region == @id_region'),
geometries_communes.query('id_region == @id_region'),
rpg
)
_exporter_surface_agricole_utile_region_par_commune_et_culture(
......@@ -125,25 +147,3 @@ def _intersecter_rpg_communes(
)
)
def charger_communes_sig(
chemin_communes_shp: Path,
referentiel_territoires: DataFrame
) -> gpd.GeoDataFrame:
communes_sig = chargeur_communes.charger_communes_shp(chemin_communes_shp)
chargeur_communes.traduire_code_insee_vers_id_crater(communes_sig)
communes = referentiel_territoires.reset_index(
).query("categorie_territoire == 'COMMUNE'"
).rename(columns={'id_territoire':'id_commune'})
outils_territoires.differences_territoires(
communes['id_commune'],
communes_sig['id_commune']
)
return communes_sig.merge(
communes[['id_commune','id_region']],
on='id_commune'
)
import geopandas as gpd
from pathlib import Path
from crater.reglages import CRS_PROJET
from crater.territoires.outils import traduire_code_insee_vers_id_commune_crater
from crater.crater_logger import log
def charger_communes_shp(
emplacement_fichier: Path,
crs=CRS_PROJET
) -> gpd.GeoDataFrame:
log.info("=> Chargement shp des communes")
return (
gpd.read_file(emplacement_fichier)
.to_crs(crs)
)
def traduire_code_insee_vers_id_crater(communes_sig: gpd.GeoDataFrame) -> gpd.GeoDataFrame:
communes_sig.rename(columns={'insee': 'id_commune'}, inplace=True)
communes_sig.id_commune = traduire_code_insee_vers_id_commune_crater(communes_sig.id_commune)
#TODO correction à modifier/supprimer si nouvelle version du shp communes
log.info("CORRECTION d'une erreur sur l'id de la commune de Bernwiller dans le fichier source")
communes_sig.loc[(communes_sig.nom == "Bernwiller"), "id_commune"] = "C-68006"
return communes_sig
......@@ -9,10 +9,10 @@ from crater.reglages import CRS_PROJET
from crater.crater_logger import log
def charger_rpg_shp(
def charger_rpg(
emplacement_fichier: Path,
crs=CRS_PROJET) -> gpd.GeoDataFrame:
log.info("=> Chargement shp du RPG " + str(emplacement_fichier))
log.info("=> Chargement du RPG " + str(emplacement_fichier))
dossier_tmp_unique = f"tmp/{uuid.uuid4().hex}"
with py7zr.SevenZipFile(emplacement_fichier, mode='r') as z:
......@@ -24,8 +24,8 @@ def charger_rpg_shp(
if len(fichiers) > 1:
raise ValueError("ERREUR : plusieurs fichiers PARCELLES_GRAPHIQUES.shp dans le dossier !")
else:
rpg_sig = gpd.read_file(fichiers[0]).to_crs(crs)
rpg = gpd.read_file(fichiers[0]).to_crs(crs)
shutil.rmtree(dossier_tmp_unique)
return rpg_sig
return rpg
from pathlib import Path
import numpy as np
import pandas
import pandas as pd
from pandas import DataFrame
import geopandas as gpd
from typing import Tuple
import crater.territoires.outils as outils_territoires
from crater.crater_logger import log
from crater.outils import DictDataFrames
from crater.surface_agricole_utile import chargeur_sau_par_commune_et_culture
from crater.territoires import chargeur_arrondissements, chargeur_mouvements_communes, \
chargeur_population_totale, chargeur_population_totale_historique, chargeur_territoires_parcel
from crater.territoires.calculateur_referentiel_territoires import charger_referentiel_territoires, \
ajouter_id_commune_de_arrondissement
from crater.territoires import chargeur_population_totale, chargeur_population_totale_historique, chargeur_territoires_parcel, chargeur_geometries_communes
from crater.territoires.calculateur_referentiel_territoires import charger_referentiel_territoires, ajouter_id_commune_de_arrondissement
from crater.territoires.chargeur_donnees_territoires import charger_donnees_territoires
from crater.territoires.outils import NUMEROS_DEPARTEMENTS_DROM
CODE_CATEGORIE_SAU_PRODUCTIVE = 'PRODUCTIVE'
CODE_CATEGORIE_SAU_PEU_PRODUCTIVE = 'PEU_PRODUCTIVE'
......@@ -20,6 +20,7 @@ CODE_CATEGORIE_SAU_PEU_PRODUCTIVE = 'PEU_PRODUCTIVE'
def calculer_donnees_territoires(
referentiel_territoires: DataFrame,
chemin_fichiers_geometries_communes: Path,
chemin_fichier_population_totale: Path,
chemin_fichier_population_totale_historique: Path,
chemin_fichiers_sau: Path,
......@@ -28,13 +29,17 @@ def calculer_donnees_territoires(
chemin_dossier_output: Path
) -> None:
sources_donnees_territoires = _charger_sources_donnees_territoires(
chemin_fichiers_geometries_communes,
chemin_fichier_population_totale,
chemin_fichier_population_totale_historique,
chemin_fichiers_sau,
chemin_fichier_correspondance_nomenclature_rpg_vers_crater,
chemin_fichier_correspondance_territoires_parcel_crater
)
outils_territoires.verifier_coherence_referentiel_avec_geometries_communes(
referentiel_territoires,
sources_donnees_territoires['geometries_communes']
)
territoires_enrichi = _ajouter_colonnes_donnees_territoires(
referentiel_territoires,
sources_donnees_territoires
......@@ -44,6 +49,7 @@ def calculer_donnees_territoires(
territoires_enrichi = territoires_enrichi[['nom_territoire',
'categorie_territoire',
'superficie_ha',
'sau_ha',
'sau_productive_ha',
'sau_peu_productive_ha',
......@@ -80,8 +86,13 @@ def _ajouter_colonnes_donnees_territoires(
) -> DataFrame: