comment filtrer les POI dans votre workflow n8n,
voici comment filtrer les POI dans votre workflow n8n, soit :
- avant le géocodage (pour réduire les appels API),
- après le géocodage (si vous préférez filtrer une fois enrichi),
- ou dans votre WebApp (Leaflet/React), pour afficher seulement certains types.
Je vous propose les trois options, car elles sont toutes utiles pour Synergia Senior.
🎯 OBJECTIF
👉 Vous voulez filtrer certains types de POI
(ex. : médecins, pharmacies, infirmiers, cabinets spécialisés, etc.)
Votre fichier Excel contient :
| nom_poi | type_poi | adresse | code_postal | ville |
Et vous voulez obtenir seulement les POI dont le champ type_poi correspond à une liste autorisée.
✅ OPTION 1 — Filtrer les POI avant géocodage (RECOMMANDÉ)
C’est la meilleure solution pour :
✔ réduire le nombre d’appels Nominatim
✔ accélérer le workflow
✔ éviter de géocoder des POI inutiles
🔧 NOEUD : Function — filter_poi
Placez-le juste après le nœud Excel → JSON.
Voici le code n8n :
// Liste de types autorisés const allowed = [ "médecin", "pharmacie", "infirmier", "cabinet médical", "ehpad" ]; // Filtrage des items return items.filter(item => { const type = (item.json.type_poi || "").toLowerCase().trim(); return allowed.includes(type); });
Résultat :
Seuls les POI autorisés seront envoyés au géocodage.
✅ OPTION 2 — Filtrer les POI après géocodage
Si vous voulez filtrer après avoir enrichi avec lat/lon :
🔧 NOEUD : Function — filter_after_geocode
Placez-le juste avant l'export Excel.
const allowed = [ "médecin", "pharmacie", "infirmier" ]; return items.filter(item => { const t = (item.json.type_poi || "").toLowerCase().trim(); const lat = item.json.lat; const lon = item.json.lon; // On filtre aussi les lignes mal géocodées return allowed.includes(t) && lat && lon; });
🎯 Très utile si vous voulez garder seulement les POI valides.
✅ OPTION 3 — Filtrer dans la WebApp (Leaflet/Next.js)
Pour filtrer côté client (React/Leaflet), ajoutez une fonction :
const allowedTypes = ["médecin", "pharmacie", "infirmier"]; const filteredPoints = points.filter(p => allowedTypes.includes((p.type_poi || "").toLowerCase()) );
Et affichez seulement eux :
filteredPoints.forEach(poi => { L.marker([poi.lat, poi.lon]) .addTo(map) .bindPopup(`<b>${poi.nom_poi}</b><br>${poi.type_poi}`); });
⭐ BONUS : Filtrage dynamique par catégorie dans la WebApp
Pour avoir un bouton ou un sélecteur (super utile pour Synergia Senior) :
UI (React)
<select onChange={e => setFilter(e.target.value)}> <option value="all">Tous</option> <option value="médecin">Médecins</option> <option value="pharmacie">Pharmacies</option> <option value="infirmier">Infirmiers</option> </select>
Logique de filtrage :
const displayedPoints = points.filter(p => filter === "all" ? true : p.type_poi === filter );
🎯 Recommandation Synergia Senior
Pour votre cas (import POI → géocodage → affichage OSM), le meilleur combo :
| Étape | Action | Pourquoi |
|---|---|---|
| n8n | Filtrer avant géocodage | Évite de payer du temps API |
| n8n | Filtrer après géocodage | Supprime les POI dont lat/lon null |
| WebApp | Filtrer dynamiquement | UX parfaite dans la carte |
📌 Si vous voulez :
✔ Je peux vous générer le fichier JSON n8n complet (workflow) prêt à importer
✔ Je peux ajouter un filtrage par rayon autour du senior (distance en km)
✔ Ou un clustering automatique des POI sur la carte Leaflet
Souhaitez-vous :
👉 Le JSON du workflow n8n prêt à importer ?
Le JSON du workflow n8n prêt à importer ?
Voici un workflow n8n complet (en JSON) que vous pouvez importer directement dans n8n, puis ajuster (chemin du fichier Excel, e-mail dans le User-Agent, etc.).
Fonction du workflow :
📄 Excel (nom_poi, type_poi, adresse, code_postal, ville)
🔁 Filtre les types de POI autorisés
🗺️ Géocode via Nominatim (OpenStreetMap)
➕ Ajoute lat / lon
📄 Génère un Excel enrichi poi_enrichis.xlsx
🧩 JSON du workflow n8n (à importer)
{ "name": "Import POI Excel → Filtre → Geocode → Excel enrichi", "nodes": [ { "parameters": {}, "id": "ManualTrigger", "name": "Manual Trigger", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [260, 300] }, { "parameters": { "filePath": "/data/poi_import.xlsx", "binaryPropertyName": "data" }, "id": "ReadExcel", "name": "Read Excel", "type": "n8n-nodes-base.readBinaryFile", "typeVersion": 1, "position": [480, 300] }, { "parameters": { "operation": "read", "binaryProperty": "data", "options": { "firstRowAsHeader": true } }, "id": "ExcelToJSON", "name": "Excel → JSON", "type": "n8n-nodes-base.spreadsheetFile", "typeVersion": 1, "position": [700, 300] }, { "parameters": { "functionCode": "// Filtrer les POI avant géocodage\n// Adapter la liste \"allowed\" selon vos besoins\nconst allowed = [\n \"médecin\",\n \"pharmacie\",\n \"infirmier\",\n \"cabinet médical\",\n \"ehpad\"\n];\n\nreturn items.filter(item => {\n const type = (item.json.type_poi || \"\").toLowerCase().trim();\n return allowed.includes(type);\n});" }, "id": "FilterPOI", "name": "Filter POI", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [920, 300] }, { "parameters": { "functionCode": "// Construire une adresse complète pour Nominatim\nreturn items.map(item => {\n const data = item.json;\n const adresse = data.adresse || \"\";\n const cp = data.code_postal || \"\";\n const ville = data.ville || \"\";\n\n const full_address = `${adresse} ${cp} ${ville}`.trim();\n\n return {\n json: {\n ...data,\n full_address,\n }\n };\n});" }, "id": "BuildAddress", "name": "Build full_address", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [1140, 300] }, { "parameters": { "method": "GET", "url": "https://nominatim.openstreetmap.org/search", "responseFormat": "json", "jsonParameters": false, "options": { "queryParametersUi": { "parameter": [ { "name": "format", "value": "json" }, { "name": "limit", "value": "1" } ] }, "responsePropertyName": "geocode" }, "queryParametersUi": { "parameter": [ { "name": "q", "value": "={{$json[\"full_address\"]}}" } ] }, "headerParametersUi": { "parameter": [ { "name": "User-Agent", "value": "synergia-senior-n8n/1.0 (contact@example.com)" } ] } }, "id": "GeocodeNominatim", "name": "Geocode Nominatim", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [1380, 300] }, { "parameters": { "functionCode": "// Extraire lat/lon à partir de la réponse geocode\n// La propriété \"geocode\" contient la réponse JSON de Nominatim (tableau)\nreturn items.map(item => {\n const d = item.json;\n const res = d.geocode;\n\n let lat = null;\n let lon = null;\n\n if (Array.isArray(res) && res.length > 0) {\n lat = res[0].lat || null;\n lon = res[0].lon || null;\n }\n\n // on enlève geocode pour ne pas polluer l'export\n delete d.geocode;\n\n return {\n json: {\n ...d,\n lat,\n lon,\n }\n };\n});" }, "id": "AttachLatLon", "name": "Attach lat/lon", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [1620, 300] }, { "parameters": { "operation": "write", "binaryProperty": "file", "options": { "fileName": "poi_enrichis.xlsx", "fileFormat": "xlsx" } }, "id": "JSONToExcel", "name": "JSON → Excel", "type": "n8n-nodes-base.spreadsheetFile", "typeVersion": 1, "position": [1860, 300] }, { "parameters": { "fileName": "poi_enrichis.xlsx", "filePath": "/data/output", "binaryPropertyName": "file" }, "id": "WriteExcel", "name": "Write Enriched Excel", "type": "n8n-nodes-base.writeBinaryFile", "typeVersion": 1, "position": [2100, 300] } ], "connections": { "Manual Trigger": { "main": [ [ { "node": "Read Excel", "type": "main", "index": 0 } ] ] }, "Read Excel": { "main": [ [ { "node": "Excel → JSON", "type": "main", "index": 0 } ] ] }, "Excel → JSON": { "main": [ [ { "node": "Filter POI", "type": "main", "index": 0 } ] ] }, "Filter POI": { "main": [ [ { "node": "Build full_address", "type": "main", "index": 0 } ] ] }, "Build full_address": { "main": [ [ { "node": "Geocode Nominatim", "type": "main", "index": 0 } ] ] }, "Geocode Nominatim": { "main": [ [ { "node": "Attach lat/lon", "type": "main", "index": 0 } ] ] }, "Attach lat/lon": { "main": [ [ { "node": "JSON → Excel", "type": "main", "index": 0 } ] ] }, "JSON → Excel": { "main": [ [ { "node": "Write Enriched Excel", "type": "main", "index": 0 } ] ] } }, "settings": {}, "version": 2 }
🛠️ Ce que vous devez adapter après import
Dans n8n, ouvrez le workflow et ajustez :
-
Read Excel
-
filePath → chemin réel de votre fichier, par ex.
/home/n8n/data/poi_import.xlsx
-
filePath → chemin réel de votre fichier, par ex.
-
Write Enriched Excel
-
filePath → dossier de sortie, par ex.
/home/n8n/data/output
-
filePath → dossier de sortie, par ex.
-
HTTP Request – Geocode Nominatim
- Dans le header User-Agent, remplacez contact@example.com par un e-mail à vous (Nominatim le demande).
-
Filter POI
-
Dans la liste allowed :
→ ajoutez / supprimez des types selon vos colonnes Excel (type_poi).const allowed = [ "médecin", "pharmacie", "infirmier", "cabinet médical", "ehpad" ];
-
Dans la liste allowed :
Si vous voulez, je peux maintenant vous faire la version 2 du workflow qui, au lieu d’écrire un Excel, pousse directement les POI dans Odoo (synergia.poi ou res.partner) via JSON-RPC 😄