rAthus icon

Fonction nettoyage infos commune via API Geo de api.gouv.fr

rAthus | PRO | 02/07/23 01:06:25 PM UTC (Edited) | 0 ⭐ | 1546 👁️ | Never ⏰ | []
PHP |

10.23 KB

|

None

|

0 👍

/

0 👎

/*
    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