/* fonction pour compléter / nettoyer / uniformiser les infos d'une commune française en utilisant le service API Geo de api.gouv.fr, requiert un tableau contenant une ou plusieurs des clés suivantes : 'cp' => code postal de la commune recherchée, exemple : "69009" (plus fiable si accompagné de 'ville' ou 'insee') 'dep' => département de la commune recherchée, exemple : "69" (ne suffit pas seul) 'insee' => code INSEE de la commune recherchée, exemple : "69389" 'ville' => nom de la commune recherchée, exemple : "Lyon" (plus fiable si accompagné de 'cp' ou 'dep' ou 'lat' et 'lng') 'lat' => latitude de la commune recherchée, exemple : 45.7802892 'lng' => longitude de la commune recherchée, exemple : 4.8055573 */ function apigouv_get_commune($infos) { // on récupère et nettoie les différentes infos $cp = (trim($infos['cp']) and strlen(trim($infos['cp']))>2)?trim($infos['cp']):''; $dep = trim($infos['dep'])?:(trim($cp)?substr(trim($cp),0,2):''); $insee = trim($infos['insee'])?:''; $ville = trim($infos['ville'])?:''; $lat = trim($infos['lat'])?:''; $lng = trim($infos['lng'])?:''; // si on a pas assez d'infos (le département seul ne suffit pas) on arrête tout if (!$cp and !$insee and !$ville and !$lat and !$lng) return false; // liste des champs demandés à API Geo $fields = 'nom,code,codesPostaux,siren,codeDepartement,codeRegion,centre'; // on initialise le retour unique et une liste de groupes retours potentiels $ret = false; $retz = array(); // on définie le taux de fiabilité du retour, par défaut à 1 (fiabilité maximum) $fiabilite = 1; // si on a un code INSEE, on commence par tenter une récupération d'infos avec lui seul if ($insee) { $args = array('code'=>$insee); // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec un maximum d'infos if (!$ret and (!end($retz) or count(end($retz))>1)) { $args = array(); if ($cp) $args['codePostal'] = $cp; if ($dep) $args['codeDepartement'] = $dep; if ($insee) $args['code'] = $insee; if ($ville) $args['nom'] = explode(',',$ville)[0]; if ($lat) $args['lat'] = $lat; if ($lng) $args['lon'] = $lng; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec le code postal et la latitude et/ou longitude suivant dispo if (!$ret and ((!end($retz) or count(end($retz))>1) and ($cp and ($lat or $lng)))) { $args = array(); if ($cp) $args['codePostal'] = $cp; if ($lat) $args['lat'] = $lat; if ($lng) $args['lon'] = $lng; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec le nom de la ville et la latitude et/ou la longitude suivant dispo if (!$ret and ((!end($retz) or count(end($retz))>1) and ($ville and ($lat or $lng)))) { $args = array(); if ($ville) $args['nom'] = explode(',',$ville)[0]; if ($lat) $args['lat'] = $lat; if ($lng) $args['lon'] = $lng; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec le code postal et la ville si dispo if (!$ret and ((!end($retz) or count(end($retz))>1) and $ville and $cp)) { $args = array(); $args['codePostal'] = $cp; $args['nom'] = explode(',',$ville)[0]; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec la ville et le département si dispo if (!$ret and ((!end($retz) or count(end($retz))>1) and $ville and $dep)) { $args = array(); $args['nom'] = $ville; $args['codeDepartement'] = $dep; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec le CP et le département si dispo if (!$ret and ((!end($retz) or count(end($retz))>1) and $cp and $dep)) { $args = array(); $args['codePostal'] = $cp; $args['codeDepartement'] = $dep; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec le code postal si dispo if (!$ret and ((!end($retz) or count(end($retz))>1) and $cp)) { $args = array(); $args['codePostal'] = $cp; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec la ville si dispo if (!$ret and ((!end($retz) or count(end($retz))>1) and $ville)) { $args = array(); $args['nom'] = $ville; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on le prend et toutes les requêtes suivantes seront zappées if (count(end($retz))==1) $ret = end($retz)[0]; } // si on a pas eu de retour unique, on tente requête avec la latitude et la longitude si dispo if (!$ret and ((!end($retz) or count(end($retz))>1) and $lat and $lng)) { $args = array(); $args['lat'] = $lat; $args['lon'] = $lng; // on stock les résultats potentiels dans le tableau $retz[] = json_decode(file_get_contents('https://geo.api.gouv.fr/communes?'.http_build_query($args).'&fields='.$fields.'&format=json&geometry=centre'),true); // si on a un résultat unique, alors on l'exploite if (count(end($retz))==1) { // si on avait des résultats en attente alors on tente de confirmer un résultat déjà potentiel if (end($retz)) { $ret_geocoding = end($retz)[0]; $insee_geocoding = $ret_geocoding['code']; $dep_geocoding = $ret_geocoding['codeDepartement']; foreach($retz as $i => $r) { if ($i==count($retz)-1) // on ignore le groupe contenant le geocoding continue; foreach($r as $a) { $count = count($r); // si un groupe contient un résultat dont le code INSEE est strictement identique à celui du geocoding, alors on le prend et toutes les requêtes suivantes seront zappées if ($a['code']==$insee_geocoding) { $ret = $a; $fiabilite = 0.99; } // si on n'a pas trouvé de résultat avec code INSEE strict mais qu'on a un résultat dans le même département, alors on met ce résultat de côté et il sera potentiellement pris et toutes les requêtes suivantes seront zappées if (!$ret and $a['codeDepartement']==$dep_geocoding) { $ret = $a; $fiabilite = round(1/($count/2),2); } } } } // sinon on prend le résultat du geocoding et toutes les requêtes suivantes seront zappées else { $ret = end($retz)[0]; } } } // si on a pas eu de retour unique, on boucle sur la liste des groupes de retours pour trouver celui qui a donné le moins de possibilités et on récupère sa première possibilité en estiment que c'est celle qui a la plus de chances d'être la bonne if (!$ret) { $max = 0; foreach($retz as $r) { $count = count($r); if (!$count) continue; if (!$max or $count<$max) { $max = $count; $ret = $r[0]; $fiabilite = round(1/$count,2); } } } // si on a un retour on renvoie le tableau d'entrée nettoyé et complété if ($ret) { $ret = array( 'cp' => ($cp and strlen($cp)>2)?$cp:$ret['codesPostaux'][0], 'dep' => $ret['codeDepartement'], 'insee' => $insee?:$ret['code'], 'ville' => $ret['nom'], 'lat' => $lat?:$ret['centre']['coordinates'][1], 'lng' => $lng?:$ret['centre']['coordinates'][0], 'fiabilite' => $fiabilite, // taux de fiabilité du résultat, de 0 (absolument incertain) à 1 (absolument fiable) ); } // on retourne le résultat return $ret; }