Chapeau

Nous avons la demande suivante :

Je veux connaître les teneurs en Nitrates de la rivière qui passe près de chez moi et voir si ces teneurs ont tendance à augmenter ou non depuis quelques années. J'habite à Longuyon, en Meurthe et Moselle.

Voyons comment Hub'Eau peut nous aider à répondre à cette question.

 

Texte

Découpage de la demande en tâches

 

 

Réalisation des tâches

 

1 - Récupérer la liste des stations de prélèvements d'eau

 

Eléments dont j'ai besoin :

 

Avec ces éléments, je peux construire l'URL à interroger :

 

Je peux aussi utiliser la "console" de l'API pour construire cette URL. S'il y a plusieurs paramètres, ils sont séparés par le signe '&'. L'ajout de &pretty permet d'avoir une mise en forme des résultats plus lisible.

En entrant cette URL dans un navigateur Web, ou si je suis développeur, en interrogeant cette URL depuis une application informatique, j'obtiens les résultats suivants :

{
    "count": 2,
    "first": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/station_pc?libelle_commune=Longuyon&pretty&page=1&size=1000",
    "last": null,
    "prev": null,
    "next": null,
    "api_version": "2.0.0",
    "data": [
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "uri_station": "https://id.eaufrance.fr/StationMesureEauxSurface/02115725",
            "durete": null,
            "coordonnee_x": 890006,
            "coordonnee_y": 6930024,
            "code_projection": "26",
            "libelle_projection": "RGF93 / Lambert 93",
            "longitude": 5.619440747,
            "latitude": 49.441280583,
            "code_commune": "54322",
            "libelle_commune": "Longuyon",
            "code_departement": "54",
            "libelle_departement": "Meurthe-et-Moselle",
            "code_region": "44",
            "libelle_region": "Grand Est",
            "code_cours_eau": "B41-0200",
            "nom_cours_eau": null,
            "uri_cours_eau": "https://id.eaufrance.fr/CoursEau_Carthage2017/B41-0200",
            "code_masse_deau": "B1R547",
            "code_eu_masse_deau": null,
            "nom_masse_deau": null,
            "uri_masse_deau": "http://id.eaufrance.fr/MasseDEauRiviere_VEDL2019/B1R547",
            "code_eu_sous_bassin": null,
            "nom_sous_bassin": null,
            "code_bassin": null,
            "code_eu_bassin": null,
            "nom_bassin": null,
            "uri_bassin": null,
            "type_entite_hydro": "2",
            "commentaire": null,
            "date_creation": "1986-01-01",
            "date_arret": null,
            "date_maj_information": "2019-05-07",
            "finalite": null,
            "localisation_precise": "LA CRUSNES À LONGUYON",
            "nature": "0",
            "altitude_point_caracteristique": 219,
            "point_kilometrique": null,
            "premier_mois_annee_etiage": null,
            "superficie_bassin_versant_reel": null,
            "superficie_bassin_versant_topo": 258.47,
            "geometry": {
                "type": "Point",
                "crs": {
                    "type": "name",
                    "properties": {
                        "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
                    }
                },
                "coordinates": [
                    5.619440746825687,
                    49.44128058252017
                ]
            },
            "uri_sous_bassin": null
        },
        {
            "code_station": "02115796",
            "libelle_station": "L'OTHAIN À SAINT-JEAN-LES-LONGUYON",
            "uri_station": "https://id.eaufrance.fr/StationMesureEauxSurface/02115796",
            "durete": null,
            "coordonnee_x": 880332,
            "coordonnee_y": 6930499,
            "code_projection": "26",
            "libelle_projection": "RGF93 / Lambert 93",
            "longitude": 5.486370684,
            "latitude": 49.44835827,
            "code_commune": "54476",
            "libelle_commune": "Saint-Jean-lès-Longuyon",
            "code_departement": "54",
            "libelle_departement": "Meurthe-et-Moselle",
            "code_region": "44",
            "libelle_region": "Grand Est",
            "code_cours_eau": null,
            "nom_cours_eau": null,
            "uri_cours_eau": null,
            "code_masse_deau": null,
            "code_eu_masse_deau": null,
            "nom_masse_deau": null,
            "uri_masse_deau": null,
            "code_eu_sous_bassin": null,
            "nom_sous_bassin": null,
            "code_bassin": null,
            "code_eu_bassin": null,
            "nom_bassin": null,
            "uri_bassin": null,
            "type_entite_hydro": "2",
            "commentaire": null,
            "date_creation": "2018-01-01",
            "date_arret": "2019-12-31",
            "date_maj_information": "2019-11-08",
            "finalite": null,
            "localisation_precise": "L'OTHAIN À SAINT-JEAN-LES-LONGUYON",
            "nature": "0",
            "altitude_point_caracteristique": 202,
            "point_kilometrique": null,
            "premier_mois_annee_etiage": null,
            "superficie_bassin_versant_reel": null,
            "superficie_bassin_versant_topo": null,
            "geometry": {
                "type": "Point",
                "crs": {
                    "type": "name",
                    "properties": {
                        "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
                    }
                },
                "coordinates": [
                    5.4863706839407325,
                    49.44835826996893
                ]
            },
            "uri_sous_bassin": null
        }
    ]
}

On se rend compte qu'on récupère beaucoup de paramètres qui ne nous intéressent pas forcément. Pour réduire la liste des paramètres retournés, on utilise l'attribut fields suivi de la liste des éléments à retourner séparés par une virgule.

Dans notre cas, on voudrait connaître simplement le nom et le code de la station, le cours d'eau sur lequel elle est située, et la commune pour vérifier. Nous n'allons donc utiliser que les éléments code_station, libelle_station, localisation_precise, code_commune, libelle_commune, code_cours_eau, nom_cours_eau.

Notre URL devient donc :


Attention à ne pas inclure d'espaces dans l'URL !

 

Cette nouvelle requête nous fournit le résultat suivant :

{
    "count": 2,
    "first": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/station_pc?libelle_commune=Longuyon&pretty&fields=code_station,libelle_station,localisation_precise,code_commune,libelle_commune,code_cours_eau,nom_cours_eau&page=1&size=1000",
    "last": null,
    "prev": null,
    "next": null,
    "api_version": "2.0.0",
    "data": [
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "code_commune": "54322",
            "libelle_commune": "Longuyon",
            "code_cours_eau": "B41-0200",
            "nom_cours_eau": null,
            "localisation_precise": "LA CRUSNES À LONGUYON"
        },
        {
            "code_station": "02115796",
            "libelle_station": "L'OTHAIN À SAINT-JEAN-LES-LONGUYON",
            "code_commune": "54476",
            "libelle_commune": "Saint-Jean-lès-Longuyon",
            "code_cours_eau": null,
            "nom_cours_eau": null,
            "localisation_precise": "L'OTHAIN À SAINT-JEAN-LES-LONGUYON"
        }
    ]
}

Ces résultats nous disent qu'il existe une station sur la commune de Longuyon, qui s'appelle LA CRUSNES à LONGUYON, de code 02115725, sur le cours d'eau La Crusnes.

 

2 - Identifier les codes de la ou des stations pertinentes

Dans notre cas, nous avons une station de code 02115725.

 

3 - Récupérer les résultats des analyses de nitrates à la station depuis 2013

 

Eléments dont j'ai besoin :

  • l'URL de base de l'opération permettant d'interroger les analyses physico-chimiques de l'API Qualité des cours d'eau : http://hubeau.eaufrance.fr/api/v2/qualite_rivieres/analyse_pc? ;
  • le nom de l'attribut permettant de préciser le code de la station : code_station ;
  • le code de la station : 02115725 ;
  • le nom de l'attribut permettant de préciser la substance recherchée (qu'on appelle paramètre) : libelle_parametre ;
  • le nom du paramètre recherché : Nitrates ;
  • le nom de l'attribut permettant de définir la date de début : date_debut_prelevement ;
  • la période recherchée : on veut les résultats depuis 2013, on écrira donc date_debut_prelevement=2013-01-01 ;
  • la qualification souhaitée des résultats : on ne va demander que les résultats dont la qualification a été jugée correcte : code_qualification=1 ;
  • les éléments que l'on veut avoir dans la réponse (optionnel) : code_station,libelle_station,code_parametre,libelle_parametre,date_prelevement,resultat,
    symbole_unite,code_remarque,mnemo_remarque,code_statut,mnemo_statut,code_qualification,libelle_qualification
    .

 

Avec ces éléments, je peux construire l'URL à interroger :

 

Voici un extrait des résultats :

{
    "count": 89,
    "first": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/analyse_pc?code_station=02115725&libelle_parametre=Nitrates&date_debut_prelevement=2013-01-01&code_qualification=1&pretty&fields=code_station,libelle_station,code_parametre,libelle_parametre,date_prelevement,resultat,symbole_unite,code_remarque,mnemo_remarque,code_statut,mnemo_statut,code_qualification,libelle_qualification&page=1&size=1000",
    "last": null,
    "prev": null,
    "next": null,
    "api_version": "2.0.0",
    "data": [
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2013-01-22",
            "code_parametre": "1340",
            "libelle_parametre": "Nitrates",
            "resultat": 25,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1",
            "mnemo_remarque": "Résultat > seuil de quantification et < au seuil de saturation ou Résultat = 0",
            "code_statut": "2",
            "mnemo_statut": "Donnée contrôlée niveau 1 (données contrôlées)",
            "code_qualification": "1",
            "libelle_qualification": "Correcte"
        },
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2013-02-19",
            "code_parametre": "1340",
            "libelle_parametre": "Nitrates",
            "resultat": 23,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1",
            "mnemo_remarque": "Résultat > seuil de quantification et < au seuil de saturation ou Résultat = 0",
            "code_statut": "2",
            "mnemo_statut": "Donnée contrôlée niveau 1 (données contrôlées)",
            "code_qualification": "1",
            "libelle_qualification": "Correcte"
        },
...
...
...
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2020-12-14",
            "code_parametre": "1340",
            "libelle_parametre": "Nitrates",
            "resultat": 37,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1",
            "mnemo_remarque": "Résultat > seuil de quantification et < au seuil de saturation ou Résultat = 0",
            "code_statut": "2",
            "mnemo_statut": "Donnée contrôlée niveau 1 (données contrôlées)",
            "code_qualification": "1",
            "libelle_qualification": "Correcte"
        }
    ]
}

Hub'Eau nous renvoie 89 résultats correspondant à notre demande (attribut count en première ligne de la réponse), sur une période s'étalant du 22 janvier 2013 au 14 décembre 2020.

 

Taille des pages de réponse

Intéressons-nous un moment à la taille des pages de réponse. Jusqu'à présent, nous n'avons pas précisé cette taille. Hub'Eau a donc utilisé la valeur par défaut de 1000 résultats par page. Maintenant, demandons par exemple des pages de 20 résultats maximum : nous allons ajouter l'élément &size=20 à notre requête :

Voici un extrait de la nouvelle réponse :

{
    "count": 89,
    "first": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/analyse_pc?code_station=02115725&libelle_parametre=Nitrates&date_debut_prelevement=2013-01-01&code_qualification=1&pretty&fields=code_station,libelle_station,code_parametre,libelle_parametre,date_prelevement,resultat,symbole_unite,code_remarque,mnemo_remarque,code_statut,mnemo_statut,code_qualification,libelle_qualification&page=1&size=20",
    "last": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/analyse_pc?code_station=02115725&libelle_parametre=Nitrates&date_debut_prelevement=2013-01-01&code_qualification=1&pretty&fields=code_station,libelle_station,code_parametre,libelle_parametre,date_prelevement,resultat,symbole_unite,code_remarque,mnemo_remarque,code_statut,mnemo_statut,code_qualification,libelle_qualification&page=5&size=20",
    "prev": null,
    "next": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/analyse_pc?code_station=02115725&libelle_parametre=Nitrates&date_debut_prelevement=2013-01-01&code_qualification=1&pretty&fields=code_station,libelle_station,code_parametre,libelle_parametre,date_prelevement,resultat,symbole_unite,code_remarque,mnemo_remarque,code_statut,mnemo_statut,code_qualification,libelle_qualification&page=2&size=20",
    "api_version": "2.0.0",
    "data": [
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2013-01-22",
            "code_parametre": "1340",
            "libelle_parametre": "Nitrates",
            "resultat": 25,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1",
            "mnemo_remarque": "Résultat > seuil de quantification et < au seuil de saturation ou Résultat = 0",
            "code_statut": "2",
            "mnemo_statut": "Donnée contrôlée niveau 1 (données contrôlées)",
            "code_qualification": "1",
            "libelle_qualification": "Correcte"
        },
...
...
...
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2014-12-22",
            "code_parametre": "1340",
            "libelle_parametre": "Nitrates",
            "resultat": 22.5,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1",
            "mnemo_remarque": "Résultat > seuil de quantification et < au seuil de saturation ou Résultat = 0",
            "code_statut": "2",
            "mnemo_statut": "Donnée contrôlée niveau 1 (données contrôlées)",
            "code_qualification": "1",
            "libelle_qualification": "Correcte"
        }
    ]
}

Nous avons bien sûr toujours 89 résultats correspondant à notre demande, par contre la première page ne liste que les 20 premiers. L'attribut next contient l'URL à appeler pour avoir les 20 prochains résultats (notez l'élément &page=2 en fin d'URL). L'attribut last contient l'URL de la dernière page de résultats. On constate qu'il y a 5 pages au total : pour obtenir la totalité des résultats, il faudra appeler successivement 5 URL.

En pratique, vous pouvez utiliser la taille par défaut de 1000 résultats par page. S'il se produit des déconnexions ou des erreurs dans la récupération des résultats, il faudra baisser cette taille.

A noter que la profondeur maximale de recherche est égale à 20 000. Celà signifie que Hub'Eau est limité à 20 000 résultats par jeu de requêtes : (nombre de pages de résultats) * (taille des pages) doit être inférieur à 20 000, quelle que soit la taille des pages. Avec une taille de page par défaut de 1000, vous ne pourrez avoir au maximum que 20 pages de résultats (les résultats suivants ne seront pas retournés par Hub'Eau). Si une requête doit ramener plus de 20 000 résultats, celà signifie qu'elle n'est pas assez discriminante, et qu'elle doit être découpée en plusieurs sous-requêtes.

 

Ordre de tri des résultats

Vous avez du constater que les résultats sont présentés par dates de prélèvement croissantes par défaut. Pour changer ce comportement, il faut ajouter l'élément &sort=desc à l'URL.

renvoie :

{
    "count": 89,
    "first": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/analyse_pc?code_station=02115725&libelle_parametre=Nitrates&date_debut_prelevement=2013-01-01&code_qualification=1&pretty&fields=code_station,libelle_station,code_parametre,libelle_parametre,date_prelevement,resultat,symbole_unite,code_remarque,mnemo_remarque,code_statut,mnemo_statut,code_qualification,libelle_qualification&sort=desc&page=1&size=1000",
    "last": null,
    "prev": null,
    "next": null,
    "api_version": "2.0.0",
    "data": [
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2020-12-14",
            "code_parametre": "1340",
            "libelle_parametre": "Nitrates",
            "resultat": 37,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1",
            "mnemo_remarque": "Résultat > seuil de quantification et < au seuil de saturation ou Résultat = 0",
            "code_statut": "2",
            "mnemo_statut": "Donnée contrôlée niveau 1 (données contrôlées)",
            "code_qualification": "1",
            "libelle_qualification": "Correcte"
        },
...
...
...
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2013-01-22",
            "code_parametre": "1340",
            "libelle_parametre": "Nitrates",
            "resultat": 25,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1",
            "mnemo_remarque": "Résultat > seuil de quantification et < au seuil de saturation ou Résultat = 0",
            "code_statut": "2",
            "mnemo_statut": "Donnée contrôlée niveau 1 (données contrôlées)",
            "code_qualification": "1",
            "libelle_qualification": "Correcte"
        }
    ]
}

 

Valeurs multiples pour un attribut

Enfin, il est possible d'interroger plusieurs stations en même temps : il faut construire l'URL avec code_station=code1,code2,code3 (un maximum de 200 codes stations est autorisé). Par exemple :

va lister tous les résultats des analyses de nitrates depuis le 1er août 2016 aux 5 stations dont le code est spécifié :

{
    "count": 148,
    "first": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/analyse_pc?code_station=02115725,02115650,02115685,02115700,02115715&libelle_parametre=Nitrates&date_debut_prelevement=2016-08-01&code_qualification=1&pretty&fields=code_station,libelle_station,libelle_parametre,date_prelevement,resultat,symbole_unite,code_remarque&sort=desc&page=1&size=1000",
    "last": null,
    "prev": null,
    "next": null,
    "api_version": "2.0.0",
    "data": [
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2020-12-14",
            "libelle_parametre": "Nitrates",
            "resultat": 37,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1"
        },
        {
            "code_station": "02115650",
            "libelle_station": "LA CHIERS À CONS-LA-GRANDVILLE",
            "date_prelevement": "2020-12-14",
            "libelle_parametre": "Nitrates",
            "resultat": 21,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1"
        },
...
...
...
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON",
            "date_prelevement": "2016-08-24",
            "libelle_parametre": "Nitrates",
            "resultat": 11.5,
            "symbole_unite": "mg(NO3)/L",
            "code_remarque": "1"
        }
    ]
}

 

Interrogation géographique par distance

Les stations interrogées lors de la requête précédente sont les stations les plus proches de La Crusnes à Longuyon, station qui nous sert d'exemple depuis le début. Pour identifier ces stations, nous avons utilisé une requête géographique avec les attributs longitude, latitude et distance qui recherche les objets présents dans un cercle de centre le point de coordonnées longitude, latitude et de rayon distance.

La première requête de ce tutoriel nous a fourni les coordonnées de la station La Crusnes à Longuyon :

      "coordinates" : [ 5.61944074682569, 49.4412805825202 ]

 

En interrogeons Hub'Eau, nous sommes en mesure de récupérer la liste des stations proches avec la requête suivante :

qui nous fournit le code et le libellé des stations dans un rayon de 8 km autour de la station La Crusnes à Longuyon :

{
    "count": 5,
    "first": "https://hubeau.eaufrance.fr/api/v2/qualite_rivieres/station_pc?longitude=5.62&latitude=49.44&distance=8&exact_count=true&format=json&fields=code_station,libelle_station&pretty&page=1&size=20",
    "last": null,
    "prev": null,
    "next": null,
    "api_version": "2.0.0",
    "data": [
        {
            "code_station": "02115650",
            "libelle_station": "LA CHIERS À CONS-LA-GRANDVILLE"
        },
        {
            "code_station": "02115685",
            "libelle_station": "LE RUISSEAU DE NANHEUL À PIERREPONT"
        },
        {
            "code_station": "02115700",
            "libelle_station": "LA CRUSNES À PIERREPONT"
        },
        {
            "code_station": "02115715",
            "libelle_station": "LE RUISSEAU DES EURANTES À ARRANCY-SUR-CRUSNES"
        },
        {
            "code_station": "02115725",
            "libelle_station": "LA CRUSNES À LONGUYON"
        }
    ]
}

Changeons de format de réponse

Nous avons utilisé pour l'instant les opérations permettant de récupérer des résultats au format JSON, très utilisé par les développeurs. Pour exploiter les résultats dans un tableur, il est sans doute plus judicieux d'utiliser les opérations renvoyant des résultats au format CSV. Il suffit d'ajouter .csv à l'URL de base, par exemple l'URL :

vous permet d'enregistrer un fichier CSV que l'on visualise ici dans un bloc-note :

 

"code_station";"date_prelevement";"libelle_parametre";"resultat";"symbole_unite";"code_remarque"
"02115725";"2013-01-22";"Nitrates";"25.0";"mg(NO3)/L";"1"
"02115725";"2013-01-22";"Nitrates";"25.0";"mg(NO3)/L";"1"
"02115725";"2013-01-22";"Nitrates";"25.0";"mg(NO3)/L";"1"
"02115725";"2013-02-19";"Nitrates";"23.0";"mg(NO3)/L";"1"
"02115725";"2013-02-19";"Nitrates";"23.0";"mg(NO3)/L";"1"
"02115725";"2013-02-19";"Nitrates";"23.0";"mg(NO3)/L";"1"
"02115725";"2013-03-19";"Nitrates";"30.0";"mg(NO3)/L";"1"
"02115725";"2013-03-19";"Nitrates";"30.0";"mg(NO3)/L";"1"
"02115725";"2013-03-19";"Nitrates";"30.0";"mg(NO3)/L";"1"
"02115725";"2013-04-16";"Nitrates";"25.0";"mg(NO3)/L";"1"
...
"02115725";"2016-10-18";"Nitrates";"15.3";"mg(NO3)/L";"1"
"02115725";"2016-11-14";"Nitrates";"31.3";"mg(NO3)/L";"1"
"02115725";"2016-12-09";"Nitrates";"20.5";"mg(NO3)/L";"1"

 

4 - Intégrer les résultats dans un tableur de type Excel pour visualiser leur évolution.

Nous allons utiliser Excel, qui lit directement les fichiers CSV. La commande Fichier, Ouvrir (en sélectionnant les fichiers de type Texte prn,txt,csv) permet d'ouvrir le fichier et de répartir les différentes informations en colonnes.

Selon la configuration de votre ordinateur, il faudra remplacer les symboles décimaux '.' en ',' pour que les nombres soient correctement reconnus. Vous pouvez alors insérer un graphique de type Nuage de point et visualiser graphiquement les résultats :

Teneur en Nitrates dans la Crusnes à Longuyon

Il ne vous reste plus qu'à essayer : rendez-vous sur la page de l'API Qualité des cours d'eau !