/*
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;
}
Comments