Je cherchais une liste des structures environnementales de Dordogne : des pistes de stage et des partenaires possibles. J'ai testé trois sources, de la plus simple à la plus lourde. La dernière, la base SIRENE de l'INSEE, m'a obligé à passer par Python et a abouti à une carte interactive.
Ce qui marche
- Le CPIE Périgord-Limousin : un bon point d'entrée, mais son annuaire PDF date d'environ 2016.
- L'Annuaire des Entreprises (gouv.fr) : des filtres par département et par code APE, mais le tri se fait à la main.
- La base SIRENE + 2 scripts Python : 5 051 établissements extraits pour le 24, placés sur une carte interactive.
Ce que je retiens
- Le code APE et le code NAF sont le même code (4 chiffres + 1 lettre).
- Les fichiers SIRENE dépassent la limite de Calc (1 048 576 lignes) → Python est indispensable.
Résultat non validé : le code 94.99Z regroupe toutes les associations « par adhésion volontaire ». La carte contient donc aussi des associations qui n'ont rien d'environnemental (comités des fêtes, clubs…). Sur les 5 051 établissements, 1 142 sont fermés et le script ne les écarte pas encore. Seuls ≈ 1 929 établissements actifs ont des coordonnées. Un tri reste à faire.
1. Contexte
Le but : constituer une liste des structures environnementales du département 24.
J'ai commencé par le réseau que je connaissais, le CPIE. J'ai ensuite élargi à l'Annuaire des Entreprises, puis à la base nationale SIRENE. Chaque source est plus complète que la précédente, mais aussi plus lourde à exploiter.
2. Source 1 – Le CPIE Périgord-Limousin : un modeste annuaire
Le réseau CPIE est un bon point de départ, mais son annuaire est daté.
Le CPIE (Centre Permanent d'Initiatives pour l'Environnement) du Périgord-Limousin a été créé en 1994. Il a été labellisé en 2001, puis confirmé en 2011 pour 10 ans. Les CPIE sont des associations issues d'initiatives citoyennes locales. Ils agissent dans deux domaines :
- la sensibilisation et l'éducation de tous à l'environnement ;
- l'accompagnement des territoires, au service des politiques publiques et des projets d'acteurs.
Site : cpie-perigordlimousin.org. L'annuaire PDF date probablement de 2016 : vérifiez que les structures existent toujours avant de les contacter.
3. Source 2 – L'Annuaire des Entreprises (gouv.fr)
Le service officiel de l'État est plus exhaustif et se filtre par code APE.
L'Annuaire des Entreprises centralise gratuitement les données d'immatriculation des entreprises, administrations et associations françaises. Chaque fiche donne l'identité légale, les coordonnées officielles, les effectifs et les dirigeants déclarés.
Étape 1 – Comprendre les codes APE / NAF
À savoir : le code NAF et le code APE sont le même code, attribué par l'INSEE à l'immatriculation. On parle de code NAF pour la nomenclature complète, et de code APE pour l'activité principale d'une structure donnée.
Voici les codes les plus utilisés par les associations environnementales :
| Code | Activité | Exemples de structures |
|---|---|---|
| 94.99Z | Autres organisations fonctionnant par adhésion volontaire | La plupart des associations environnementales, CPIE |
| 91.04Z | Gestion des jardins botaniques, zoologiques et des réserves naturelles | Conservatoires d'espaces naturels, réserves |
| 72.19Z | Recherche-développement en autres sciences physiques et naturelles | Études naturalistes, inventaires de biodiversité |
| 85.59B | Autres enseignements | Éducation à l'environnement, animations scolaires |
Étape 2 – Lancer la recherche
Rendez-vous sur annuaire-des-entreprises.gouv.fr. Filtrez par département (24) et par code APE. La liste obtenue reste à trier à la main.
4. Source 3 – La base SIRENE de l'INSEE : la grosse cavalerie
C'est la base nationale complète, mise à jour chaque jour, mais trop volumineuse pour un tableur.
La base SIRENE enregistre l'état civil de toutes les entreprises, associations et institutions publiques établies en France. Chaque structure a un numéro SIREN, chaque établissement un numéro SIRET. Elle se télécharge gratuitement sur data.gouv.fr.
Deux fichiers m'intéressent :
StockUniteLegale: la structure (nom, catégorie juridique, code APE), identifiée par son SIREN ;StockEtablissement: chaque lieu d'activité (adresse, coordonnées), identifié par son SIRET.
Ces CSV comptent des millions de lignes. Calc s'arrête à 1 048 576 lignes : j'ai donc écrit deux scripts Python, lancés dans Thonny.
Étape 3 – Script 1 : filtrer les associations
Le script Script_filtres_assos.py lit les deux fichiers l'un après l'autre (code complet en annexe A).
- Passe 1 sur
StockUniteLegale: il garde les structures des 4 codes APE ciblés qui ont une forme associative (catégorie juridique 92xx ou identifiant RNA). Il mémorise leur SIREN et leur nom. - Passe 2 sur
StockEtablissement: il garde les établissements du ou des départements saisis dont le SIREN est mémorisé. - Sortie :
associations_environnement_carte.csv, avec le nom de l'association ajouté en première colonne.
Au lancement, le script vous demande le chemin de chaque fichier, puis le ou les départements (par exemple 24 ou 24,33,19).
Étape 4 – Script 2 : générer la carte
Comme dans le csv se trouvent les coordonnées GPS des structures, on est à 2 clics d'une carte (install folium et d'autres bibliothèques nécessaires)
Le script Script_generateur_carte.py transforme le CSV en carte web (code complet en annexe B).
- Il convertit les coordonnées Lambert 93 (EPSG:2154) en latitude / longitude GPS (EPSG:4326) avec la bibliothèque
pyproj. - Il construit la carte avec
folium, sur le fond OpenStreetMap France, et regroupe les points proches (MarkerCluster). - Chaque point affiche le nom de l'association, son code postal et sa commune.
- Sortie :
carte_associations_dordogne.html, à ouvrir dans un navigateur.
| Paramètre | Valeur | Pourquoi | Si vous la changez |
|---|---|---|---|
codes_cibles |
94.99Z, 91.04Z, 72.19Z, 85.59B | Codes APE des associations environnementales | Ajoutez ou retirez des codes pour élargir ou resserrer la recherche |
| Département | 24 | Saisi au lancement du script 1 | Le script 2 filtre aussi sur « 24 » : modifiez-le de la même façon |
location / zoom_start |
[45.1847, 0.7212] / 10 | Centre et cadrage de la carte sur Périgueux | Recentrez la carte pour un autre département |
tiles |
OpenStreetMap France | Fond de carte en français, sans blocage | Un autre serveur de tuiles change l'aspect de la carte |
Télécharger la carte : carte_associations_dordogne.html (3,6 Mo). Enregistrez le fichier, puis ouvrez-le dans votre navigateur.
Étape 5 – Les chiffres obtenus
Le filtrage donne beaucoup de résultats, mais tous ne sont pas utilisables. Il faudrait faire un tri dans le csv des associations.
| Élément | Valeur |
|---|---|
| Établissements extraits (24) | 5 051 |
| Associations distinctes (SIREN) | 4 422 |
| Établissements actifs / fermés | 3 909 / 1 142 |
| Actifs avec coordonnées (cartographiables) | ≈ 1 929 |
| Établissements en 94.99Z | 4 643 |
Télécharger les données : associations_environnement_carte.csv (1,2 Mo, liste brute non triée). Le fichier est en UTF-8 avec la virgule comme séparateur : choisissez ces options à l'ouverture dans Calc.
5. Les erreurs qui m'ont appris quelque chose
Chaque étape a eu sa difficulté.
- Ouvrir SIRENE dans Calc : impossible, le fichier dépasse la limite de lignes.
- Le code 94.99Z ratisse trop large : il ramène toutes sortes d'associations, pas seulement environnementales.
- Le code APE d'un établissement peut différer de celui de sa structure : on trouve du 91.3E ou du 88.99B dans le résultat.
- Le script garde les établissements fermés : il faudra filtrer sur l'état administratif.
Annexes – Les scripts Python
Les deux scripts se lancent dans Thonny. Installez d'abord les bibliothèques de la carte : folium, pandas et pyproj (menu Outils → Gérer les paquets). Lancez le script A, puis le script B dans le même dossier.
Annexe A – Script_filtres_assos.py
Afficher le code (99 lignes)
import csv
import os
print("=== ÉTAPE 1 : Identification et mémorisation des noms & SIREN des associations ===")
unite_file = input("Copier le chemin d'accès du fichier StockUniteLegale .csv ici : ").strip('"')
if not os.path.exists(unite_file) or os.path.isdir(unite_file):
print("Erreur : Fichier StockUniteLegale invalide ou introuvable.")
exit()
codes_cibles = {'94.99Z', '91.04Z', '72.19Z', '85.59B'}
associations_infos = {} # Dictionnaire pour stocker siren -> nom de l'association
compteur_unite_total = 0
print("Analyse des unités légales en cours...\n")
with open(unite_file, mode='r', encoding='utf-8', errors='ignore') as f:
reader = csv.DictReader(f, delimiter=',')
for row in reader:
compteur_unite_total += 1
ape = row.get('activitePrincipaleUniteLegale', '').strip().upper()
if ape in codes_cibles:
cat_jur = row.get('categorieJuridiqueUniteLegale', '').strip()
id_asso = row.get('identifiantAssociationUniteLegale', '').strip()
# Vérification de la forme associative
if cat_jur.startswith('92') or (id_asso != '' and id_asso.lower() != 'nan'):
siren = row.get('siren', '').strip()
# Récupération du nom (denomination ou nom/prenom si personne physique)
denomination = row.get('denominationUniteLegale', '').strip()
if not denomination or denomination.lower() == 'nan':
nom = row.get('nomUniteLegale', '').strip()
prenom = row.get('prenom1UniteLegale', '').strip()
denomination = f"{nom} {prenom}".strip()
if siren:
associations_infos[siren] = denomination if denomination else "Nom inconnu"
if compteur_unite_total % 500000 == 0:
print(f"Lignes unités légales analysées : {compteur_unite_total:,} | Associations ciblées trouvées : {len(associations_infos):,}", end="\r", flush=True)
print("\n" + "="*50)
print(f"-> {len(associations_infos):,} associations environnementales mémorisées.\n")
print("=== ÉTAPE 2 : Filtrage géographique, adresses et coordonnées ===")
etab_file = input("Copier le chemin d'accès du fichier StockEtablissement .csv ici : ").strip('"')
if not os.path.exists(etab_file) or os.path.isdir(etab_file):
print("Erreur : Fichier StockEtablissement invalide ou introuvable.")
exit()
saisie_deps = input("Entrez le ou les numéros de département à cibler (ex: 24 ou 24,33,19) : ").strip()
departements_cibles = {d.strip() for d in saisie_deps.split(',') if d.strip()}
if not departements_cibles:
print("Aucun département saisi. Arrêt.")
exit()
output_file = 'associations_environnement_carte.csv'
compteur_matches = 0
compteur_total = 0
print(f"\nRecherche des établissements pour le(s) département(s) {departements_cibles}...\n")
with open(etab_file, mode='r', encoding='utf-8', errors='ignore') as f_in, \
open(output_file, mode='w', encoding='utf-8', newline='') as f_out:
reader = csv.DictReader(f_in, delimiter=',')
# On ajoute une colonne 'nomAssociation' au début des en-têtes du fichier de sortie
fieldnames = ['nomAssociation'] + reader.fieldnames
writer = csv.DictWriter(f_out, fieldnames=fieldnames, delimiter=',')
writer.writeheader()
for row in reader:
compteur_total += 1
# 1. Vérification du département via le code postal
cp = row.get('codePostalEtablissement', '').strip()
if not cp or cp[:2] not in departements_cibles:
if compteur_total % 500000 == 0:
print(f"Lignes établissements analysées : {compteur_total:,} | Matchs trouvés : {compteur_matches}", end="\r", flush=True)
continue
# 2. Vérification si le SIREN appartient à nos associations ciblées
siren = row.get('siren', '').strip()
if siren in associations_infos:
# On ajoute le nom de l'association dans la ligne
row['nomAssociation'] = associations_infos[siren]
writer.writerow(row)
compteur_matches += 1
if compteur_total % 500000 == 0:
print(f"Lignes établissements analysées : {compteur_total:,} | Matchs trouvés : {compteur_matches}", end="\r", flush=True)
print("\n" + "="*50)
print(f"Terminé ! {compteur_matches} associations correspondantes trouvées avec leurs adresses et coordonnées.")
print(f"Résultat sauvegardé dans : {output_file}")
Annexe B – Script_generateur_carte.py
Afficher le code (79 lignes)
import folium
import pandas as pd
from pyproj import Transformer
# 1. Chargement de votre fichier CSV
csv_file = 'associations_environnement_carte.csv'
print('Chargement des données...')
df = pd.read_csv(csv_file)
# 2. Filtrage strict sur la Dordogne (codes postaux commençant par 24)
df['codePostalEtablissement'] = (
df['codePostalEtablissement'].astype(str).str.zfill(5)
)
df_dordogne = df[
df['codePostalEtablissement'].str.startswith('24')
& df['coordonneeLambertAbscisseEtablissement'].notna()
& df['coordonneeLambertOrdonneeEtablissement'].notna()
].copy()
print(f'-> {len(df_dordogne)} associations trouvées pour la Dordogne.')
# 3. Conversion des coordonnées Lambert 93 vers GPS (Latitude / Longitude)
transformer = Transformer.from_crs('EPSG:2154', 'EPSG:4326', always_xy=True)
lons, lats = [], []
for _, row in df_dordogne.iterrows():
lon, lat = transformer.transform(
row['coordonneeLambertAbscisseEtablissement'],
row['coordonneeLambertOrdonneeEtablissement'],
)
lons.append(lon)
lats.append(lat)
df_dordogne['longitude'] = lons
df_dordogne['latitude'] = lats
# 4. Création de la carte avec le serveur OpenStreetMap France (anti-blocage)
carte_dordogne = folium.Map(
location=[45.1847, 0.7212],
zoom_start=10,
tiles='https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
attr=(
'© OpenStreetMap France | Données © contributeurs'
' OpenStreetMap'
),
)
from folium.plugins import MarkerCluster
marker_cluster = MarkerCluster().add_to(carte_dordogne)
# 5. Ajout des points sur la carte
for _, row in df_dordogne.iterrows():
nom = str(row.get('nomAssociation', 'Nom inconnu'))
commune = str(row.get('libelleCommuneEtablissement', ''))
cp = str(row.get('codePostalEtablissement', ''))
popup_html = f"""
<div style="font-family: Arial; font-size: 12px; width: 220px;">
<b>{nom}</b><br>
📍 {cp} {commune}
</div>
"""
folium.Marker(
location=[row['latitude'], row['longitude']],
popup=folium.Popup(popup_html, max_width=300),
tooltip=nom[:30],
icon=folium.Icon(color='green', icon='leaf', prefix='fa'),
).add_to(marker_cluster)
# 6. Sauvegarde
output_html = 'carte_associations_dordogne.html'
carte_dordogne.save(output_html)
print(
f"\nCarte générée avec succès ! Ouvrez '{output_html}' dans votre navigateur."
)

















Aucun commentaire:
Enregistrer un commentaire
Tout commentaire nous engage ;)