Skip to content

Commit

Permalink
Add sources ign (#73)
Browse files Browse the repository at this point in the history
* typo

* correct sources

* spaces

* refacto POO

* Optimisation download.py

Corrections et todos mineurs
+ filtrage des fichiers dans 7z avant extraction
+ prise en compte d'éventuels répertoires multiples contenant les shapefiles
+ ajout des arguments à la fonction download_sources

* update gitignore

* old typos

* add source

* Update pyproject.toml

* tests download

* Mise à jour

* Update download.py

Inversion test recherche file dans yaml vs. field, date, prefix, etc.

* fix yaml

* Quick fix BDTOPO sur download

* Fix différents paramètres modulables du yaml

* Fix missing "field" parameter

* black

* Restructuration POO avec utils

* Premiers tests avec pytest

* Ajout test simulant erreur téléchargement

* Add test for yaml's syntax

* Update test_download.py

* Update test_download.py

* autopep8

* petits deplacements

* minor changes names

* add comments

* restore download

* modifs a la marge notebook

---------

Co-authored-by: thomas.grandjean <thomas.grandjean@developpement-durable.gouv.fr>
Co-authored-by: Thomas Grandjean <tgrandje@gmail.com>
  • Loading branch information
3 people authored Sep 5, 2023
1 parent e4023fb commit a5a0886
Show file tree
Hide file tree
Showing 18 changed files with 615 additions and 279 deletions.
20 changes: 10 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Guide pour aider les développeurs du package <img height="18" width="18" src="https://cdn.simpleicons.org/python/00ccff99" /> `cartiflette`

Le _package_ <img height="18" width="18" src="https://cdn.simpleicons.org/python/00ccff99" /> `cartiflette`
est une boite à outil qui répond principalement à deux objectifs:
est une boite à outil qui répond principalement à deux objectifs :

- récupérer et restructurer les données diffusées par l'IGN pour produire des fonds de carte prêts à l'emploi
- interagir en écriture (mainteneurs du package) et en lecture (tous les utilisateurs) avec l'espace de stockage des fonds de carte proposés par `cartiflette`
Expand All @@ -11,7 +11,7 @@ est une boite à outil qui répond principalement à deux objectifs:
Le package `cartiflette` est organisé en sous-packages thématiques:

- `cartiflette.utils`: une série de fonctions utilisées dans les autres sous-packages ou de fichiers de configuration utiles (comme le `sources.yaml`). Bien que certaines puissent être utiles à des utilisateurs du _package_, elles ont plutôt vocation à être des _internals_.
- `cartiflette.download`: package pour communiquer avec le site de l'IGN. Les emplacements où aller chercher les fichiers sont dans le package `utils` et ce package se charge de télécharger, écrire dans un dossier temporaire dézipper en local la source.
- `cartiflette.download`: package pour communiquer avec le site de l'IGN. Les emplacements où aller chercher les fichiers sont dans le package `utils` et ce package se charge de télécharger, écrire dans un dossier temporaire et dézipper en local la source.
Un système de _cache_ existe pour éviter de télécharger plusieurs fois le même fichier.
- `cartiflette.s3`: le package qui gère l'interaction avec le système de stockage. Les fonctions sont à deux niveaux dans ce package
+ celles qui servent à écrire sur l'espace de stockage sont utilisées exclusivement par le _pipeline_ de production des fonds de carte `cartiflette`
Expand All @@ -23,12 +23,12 @@ Un système de _cache_ existe pour éviter de télécharger plusieurs fois le m

Les principales fonctions sont les suivantes:

- `create_url_adminexpress` (_internal_): en fonction de paramètres de l'utilisateur (source, année...), récupération dans le fichier de config
- `create_url_adminexpress` (_internal_) : en fonction de paramètres de l'utilisateur (source, année...), récupération dans le fichier de config
de l'URL où aller chercher les données `IGN`
- `store_vectorfile_ign`: téléchargement des données IGN en fonction de paramètres de l'utilisateur (source, année...). Compter environ 500Mo pour les données Admin-Express et écriture dans un chemin standardisé
- `get_vectorfile_ign`: après `store_vectorfile_ign`, lecture sous forme de `DataFrame` `GeoPandas`
- `get_administrative_level_available_ign`: après `store_vectorfile_ign`, liste les niveaux administratifs disponibles
- `get_vectorfile_communes_arrondissement`: fait un `get_vectorfile_ign` sur deux niveaux administratifs, les arrondissements et les communes. Pour les trois villes à arrondissement, retire la commune et remplace par les arrondissements.
- `store_vectorfile_ign` : téléchargement des données IGN en fonction de paramètres de l'utilisateur (source, année...). Compter environ 500Mo pour les données Admin-Express et écriture dans un chemin standardisé
- `get_vectorfile_ign` : après `store_vectorfile_ign`, lecture sous forme de `DataFrame` `GeoPandas`
- `get_administrative_level_available_ign` : après `store_vectorfile_ign`, liste les niveaux administratifs disponibles
- `get_vectorfile_communes_arrondissement` : fait un `get_vectorfile_ign` sur deux niveaux administratifs, les arrondissements et les communes. Pour les trois villes à arrondissement, retire la commune et remplace par les arrondissements.

Exemple :

Expand All @@ -45,18 +45,18 @@ get_vectorfile_ign(

Bien que les fonctions de ce _package_
puissent être mises à disposition des utilisateurs finaux de `cartiflette`, elles
ont plutôt vocation à être utilisées lors de la production des fichiers de `cartiflette`
ont plutôt vocation à être utilisées lors de la production des fichiers de `cartiflette`.

## `cartiflette.s3`

Les fonctions d'écriture sur l'espace de stockage ayant vocation à être dans le _pipeline_:
Les fonctions d'écriture sur l'espace de stockage ayant vocation à être dans le _pipeline_ :

- `write_vectorfile_s3_all`
- `write_vectorfile_s3_custom_arrondissement`
- `production_cartiflette`

Les fonctions de récupération des fonds de carte ayant vocation à être mises à disposition
des utilisateurs finaux:
des utilisateurs finaux :

- `download_vectorfile_s3_all`
- `download_vectorfile_url_all`
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ A l’heure actuelle, `cartiflette` est structuré sous la forme d’un
`package` :package: `Python` :snake:. Ceci est amené à évoluer pour
faciliter encore plus la récupération de contours grâce à des API.

Tout ceci est donc amené à bien évoluer, n’hésitez pas à revenir
fréqumment sur cette page.
De nombres évolutions étant encore à venir, n’hésitez donc pas à repasser
fréquemment sur cette page.

``` python
pip install requests py7zr geopandas openpyxl tqdm s3fs PyYAML xlrd
pip install git+https://github.com/inseefrlab/cartogether
```

Pour tester le package, vous pouvez tenter de récupérer le contour des
communes de la région Normandie:
communes de la région Normandie :

``` python
import cartiflette.s3
Expand Down Expand Up @@ -94,6 +94,6 @@ ax.set_axis_off()

## Plus de détails

- Pitch du projet ici: https://10pourcent.etalab.studio/projets/insee/
- Ateliers ici:
- Pitch du projet ici : https://10pourcent.etalab.studio/projets/insee/
- Ateliers ici :
https://github.com/etalab-ia/programme10pourcent/wiki/Ateliers-Faciliter-l%E2%80%99association-de-sources-de-donn%C3%A9es-g%C3%A9ographiques-issues-de-divers-producteurs-(INSEE,-IGN,-collectivit%C3%A9s-locales%E2%80%A6)#atelier2
12 changes: 6 additions & 6 deletions README.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ la forme d'un `package` :package: `Python` :snake:.
Ceci est amené à évoluer pour faciliter encore plus
la récupération de contours grâce à des API.

Tout ceci est donc amené à bien évoluer, n'hésitez pas à
revenir fréqumment sur cette page.
De nombres évolutions étant encore à venir, nhésitez donc pas à repasser
fréquemment sur cette page.

```python
pip install requests py7zr geopandas openpyxl tqdm s3fs PyYAML xlrd
pip install git+https://github.com/inseefrlab/cartogether
```

Pour tester le package, vous pouvez tenter de récupérer
le contour des communes de la région Normandie:
le contour des communes de la région Normandie :

```{python}
import cartiflette.s3
Expand All @@ -49,7 +49,7 @@ ax = normandie.plot()
ax.set_axis_off()
```

ou des régions Ile de France, Normandie et Bourgogne
ou des régions Ile de France, Normandie et Bourgogne :


```{python}
Expand Down Expand Up @@ -81,5 +81,5 @@ ax.set_axis_off()

## Plus de détails

- Pitch du projet ici: https://10pourcent.etalab.studio/projets/insee/
- Ateliers ici: https://github.com/etalab-ia/programme10pourcent/wiki/Ateliers-Faciliter-l%E2%80%99association-de-sources-de-donn%C3%A9es-g%C3%A9ographiques-issues-de-divers-producteurs-(INSEE,-IGN,-collectivit%C3%A9s-locales%E2%80%A6)#atelier2
- Pitch du projet ici : https://10pourcent.etalab.studio/projets/insee/
- Ateliers ici : https://github.com/etalab-ia/programme10pourcent/wiki/Ateliers-Faciliter-l%E2%80%99association-de-sources-de-donn%C3%A9es-g%C3%A9ographiques-issues-de-divers-producteurs-(INSEE,-IGN,-collectivit%C3%A9s-locales%E2%80%A6)#atelier2
64 changes: 38 additions & 26 deletions cartiflette/download/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ def safe_download_write(
location = location + ext

if param_ftp is not None:
ftp = ftplib.FTP(param_ftp["hostname"], param_ftp["username"], param_ftp["pwd"])
ftp = ftplib.FTP(
param_ftp["hostname"],
param_ftp["username"],
param_ftp["pwd"])
download_pb_ftp(ftp, url, fname=location)
else:
download_pb(url, location, verify=verify, force=force)
Expand All @@ -66,7 +69,8 @@ def safe_download_write(

def create_url_adminexpress(
provider: typing.Union[list, str] = ["IGN", "opendatarchives"],
source: typing.Union[list, str] = ["EXPRESS-COG", "EXPRESS-COG-TERRITOIRE"],
source: typing.Union[list, str] = [
"EXPRESS-COG", "EXPRESS-COG-TERRITOIRE"],
year: typing.Optional[str] = None,
field: str = "metropole",
):
Expand Down Expand Up @@ -96,7 +100,8 @@ def create_url_adminexpress(
dict_source = dict_open_data[provider]["ADMINEXPRESS"][source]

if source.endswith("-TERRITOIRE"):
url = url_express_COG_territoire(year=year, provider=provider, territoire=field)
url = url_express_COG_territoire(
year=year, provider=provider, territoire=field)
else:
url = dict_source[year]["file"]

Expand All @@ -105,7 +110,8 @@ def create_url_adminexpress(

def download_admin_express(
provider: typing.Union[list, str] = ["IGN", "opendatarchives"],
source: typing.Union[list, str] = ["EXPRESS-COG", "EXPRESS-COG-TERRITOIRE"],
source: typing.Union[list, str] = [
"EXPRESS-COG", "EXPRESS-COG-TERRITOIRE"],
year: typing.Optional[str] = None,
location: str = None,
field: str = "metropole",
Expand Down Expand Up @@ -153,7 +159,8 @@ def download_admin_express(
# download 7z file
temp_file = tempfile.NamedTemporaryFile()
temp_file_raw = temp_file.name + ".7z"
out_name = safe_download_write(url, location=temp_file_raw, param_ftp=param_ftp)
out_name = safe_download_write(
url, location=temp_file_raw, param_ftp=param_ftp)
if location is None:
tmp = tempfile.TemporaryDirectory()
location = tmp.name
Expand All @@ -168,7 +175,8 @@ def download_admin_express(


def download_store_admin_express(
source: typing.Union[list, str] = ["EXPRESS-COG", "COG", "EXPRESS-COG-TERRITOIRE"],
source: typing.Union[list, str] = [
"EXPRESS-COG", "COG", "EXPRESS-COG-TERRITOIRE"],
year: typing.Optional[str] = None,
location: str = None,
provider: typing.Union[list, str] = ["IGN", "opendatarchives"],
Expand Down Expand Up @@ -201,7 +209,8 @@ def download_store_admin_express(
dict_source = dict_open_data[provider]["ADMINEXPRESS"][source]

if year is None:
year = max([i for i in dict_source.keys() if i not in ("field", "FTP")])
year = max([i for i in dict_source.keys()
if i not in ("field", "FTP")])

if location is None:
location = tempfile.gettempdir()
Expand Down Expand Up @@ -229,7 +238,8 @@ def download_store_admin_express(


def store_vectorfile_ign(
source: typing.Union[list, str] = ["EXPRESS-COG", "COG", "EXPRESS-COG-TERRITOIRE"],
source: typing.Union[list, str] = [
"EXPRESS-COG", "COG", "EXPRESS-COG-TERRITOIRE"],
year: typing.Optional[str] = None,
field: str = "metropole",
provider: typing.Union[list, str] = ["IGN", "opendatarchives"],
Expand Down Expand Up @@ -263,7 +273,8 @@ def store_vectorfile_ign(


def get_administrative_level_available_ign(
source: typing.Union[list, str] = ["EXPRESS-COG", "EXPRESS-COG-TERRITOIRE"],
source: typing.Union[list, str] = [
"EXPRESS-COG", "EXPRESS-COG-TERRITOIRE"],
year: typing.Optional[str] = None,
field: typing.Union[list, str] = [
"metropole",
Expand Down Expand Up @@ -300,7 +311,8 @@ def get_administrative_level_available_ign(
dict_source = dict_open_data["IGN"]["ADMINEXPRESS"][source]

if year is None:
year = max([i for i in dict_source.keys() if i not in ("field", "FTP")])
year = max([i for i in dict_source.keys()
if i not in ("field", "FTP")])

if isinstance(field, list):
field = field[0]
Expand All @@ -312,7 +324,8 @@ def get_administrative_level_available_ign(
for i in glob.glob(shp_location + "/*.shp")
]
if verbose:
print("\n - ".join(["Available administrative levels are :"] + list_levels))
print(
"\n - ".join(["Available administrative levels are :"] + list_levels))
return list_levels


Expand Down Expand Up @@ -385,7 +398,11 @@ def get_vectorfile_communes_arrondissement(
source=source,
)
communes = get_vectorfile_ign(
borders="COMMUNE", year=year, field="metropole", provider=provider, source=source
borders="COMMUNE",
year=year,
field="metropole",
provider=provider,
source=source,
)
communes_sans_grandes_villes = communes.loc[
~communes["NOM"].isin(["Marseille", "Lyon", "Paris"])
Expand All @@ -406,44 +423,39 @@ def get_vectorfile_communes_arrondissement(
communes_sans_grandes_villes,
arrondissement_extra_info
]
)
)

df_enrichi["INSEE_COG"] = np.where(
df_enrichi["INSEE_ARM"].isnull(),
df_enrichi["INSEE_COM"],
df_enrichi["INSEE_ARM"],
)

df_enrichi = df_enrichi.drop('INSEE_ARM', axis="columns")
df_enrichi = df_enrichi.drop("INSEE_ARM", axis="columns")

return df_enrichi


def get_cog_year(year: int = 2022):

config = import_yaml_config()

config_cog_year = config['Insee']['COG'][year]
config_root = config['Insee']['COG']['root']
config_cog_year = config["Insee"]["COG"][year]
config_root = config["Insee"]["COG"]["root"]
url_root = f"{config_root}/{config_cog_year['id']}"

urls = {
cog['alias']: f"{url_root}/{cog['filename']}" for \
key, cog in \
config_cog_year["content"].items()

}
cog["alias"]: f"{url_root}/{cog['filename']}"
for key, cog in config_cog_year["content"].items()
}

dict_cog = {
level: pd.read_csv(url)\
for level, url in urls.items()
level: pd.read_csv(url)
for level, url in urls.items()
}

return dict_cog




def get_BV(year: int = 2022):
"""
Import and Unzip Bassins de vie (Insee, format 2012)
Expand Down
4 changes: 2 additions & 2 deletions cartiflette/s3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
production_cartiflette,
list_produced_cartiflette,
duplicate_vectorfile_ign,
write_cog_s3
write_cog_s3,
)

__all__ = [
Expand All @@ -17,5 +17,5 @@
"production_cartiflette",
"list_produced_cartiflette",
"duplicate_vectorfile_ign",
"write_cog_s3"
"write_cog_s3",
]
Loading

0 comments on commit a5a0886

Please sign in to comment.