Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Récupérer données JSON d'une API météo



  • Bonjour,

    Vous êtes ma dernière chance avant que je mette tout mon projet à la poubelle !! :D
    J'essaie de créer une station météo en C++ avec Qt Creator. En fait, je l'ai déjà faite mais en python.
    Je préfère la faire en C++, tout fonctionne SAUF, le plus important : Les requetes vers le fichier JSON.

    Le fichier JSON de l'API

    coord	
      lon	3.9
      lat	43.6333
    weather	
      0	
        id	        800
        main        "Clear"
        description	"ciel dégagé"
        icon	"01n"
    base            "stations"
    main	
      temp	        284.64
      feels_like	276.17
      temp_min	284.26
      temp_max	285.15
      pressure	1014
      humidity	37
    visibility	10000
    wind	
      speed	        8.75
      deg	        350
    clouds	
      all	        0
      dt	        1616358956
    

    Ma fonction

    void MoonWeather::MoonJSONRequest()
    {
        QNetworkRequest JSON_request(QUrl
                ("https://api.openweathermap.org/data/2.5/weather?q=castelnau-le-lez&lang=fr&appid=738e9d1489491771d579f8b5db5fd21a"));
        JSON_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    
        reply = nam.post(JSON_request, QJsonDocument(loadJSONFile).toJson());
    
        while (!reply->isFinished()) { qApp->processEvents(); }
    
        loadJSONFile = QJsonDocument::fromJson(reply->readAll());
    
        JSON_object = loadJSONFile.object()["weather"].toObject();
        JSON_array  = JSON_object["0"].toArray();
        JSON_value  = JSON_array[2].toObject()["descritpion"].toString();
    
        reply->deleteLater();
    
        qDebug() << loadJSONFile;
        qDebug() << "OBJECT : " << JSON_object;
        qDebug() << "ARRAY  : " << JSON_array;
        qDebug() << "ITEM   : " << JSON_value;
    }
    

    La sortie Console

    QJsonDocument({"base":"stations","clouds":{"all":0},"cod":200,"coord":{"lat":43.6333,"lon":3.9},"dt":1616363809,"id":3028337,"main":{"feels_like":275.82,"humidity":40,"pressure":1014,"temp":284.21,"temp_max":284.26,"temp_min":284.15},"name":"Castelnau-le-Lez","sys":{"country":"FR","id":6518,"sunrise":1616305545,"sunset":1616349438,"type":1},"timezone":3600,"visibility":10000,"weather":[{"description":"ciel dégagé","icon":"01n","id":800,"main":"Clear"}],"wind":{"deg":350,"speed":8.75}})
    OBJECT :  QJsonObject({"0":null})
    ARRAY  :  QJsonArray()
    ITEM   :  ""
    

    Comme vous le voyez, "ITEM" est vide, normalement, du moins, ce que je voulais faire, il devait afficher l'élément dans [weather][0][description]... Donc "Ciel dégagé"..
    Ce qu'il ne fait pas, donc ma demande est.. Pourquoi ? quelle partie de la fonction est fausse, ca fait 3 jours que je cherche..
    Je pense que le fait qu'il ne le sorte pas dans le meme format dans la console doit jouer, mais c'est précisément le probleme, je n'arrive pas a réucpérer l'information.

    Merci à vous ;)


  • Lifetime Qt Champion

    Bonsoir,

    @Ayckinn said in Récupérer données JSON d'une API météo:

    "descritpion"

    Ne serait-ce pas plutôt "description" ?



  • @Ayckinn said in Récupérer données JSON d'une API météo:

    description

    pfff !! Si, effectivement, dyslexie, quand tu nous tient -_-'
    merci
    Mais malheureusement, cela ne résous pas mon problème une fois rectifié.. Ca m'aurait arrangé :)



  • @Ayckinn said in Récupérer données JSON d'une API météo:

    Mais malheureusement, cela ne résous pas mon problème une fois rectifié.. Ca m'aurait arrangé :)

    Je pense que tu n'as pas regardé en détails ton document JSON, si je le remet en forme de façon plus lisible:

    {
        "base":"stations",
        "clouds":{
            "all":0
        },
        "cod":200,
        "coord":{
            "lat":43.6333,
            "lon":3.9
        },
        "dt":1616363809,
        "id":3028337,
        "main":{
            "feels_like":275.82,
            "humidity":40,
            "pressure":1014,
            "temp":284.21,
            "temp_max":284.26,
            "temp_min":284.15
        },
        "name":"Castelnau-le-Lez",
        "sys":{
            "country":"FR",
            "id":6518,
            "sunrise":1616305545,
            "sunset":1616349438,
            "type":1
        },
        "timezone":3600,
        "visibility":10000,
        "weather":[
            {
                "description":"ciel dégagé",
                "icon":"01n",
                "id":800,
                "main":"Clear"
            }
        ],
        "wind":{
            "deg":350,
            "speed":8.75
        }
    }
    

    Moi je ferais:

        JSON_array  = loadJSONFile.object()["weather"].toArray();
        JSON_object = JSON_array.first().toObject();
        JSON_value  = JSON_object ["description"].toString();
    

    EDIT:
    quelques explications:

    • l'élément ROOT est un objet JSON => loadJSONFile.object()
    • de l'objet ROOT, on cherche le membre weather qui est une table ==> ["weather"].toArray()
    • on veut le premier élément, qui est un objet ==> JSON_array.first().toObject();
    • et de cet objet on veut le membre description qui est une chaîne de caractères ==> JSON_object ["description"].toString()


  • @KroMignon

    MERCI BEAUCOUP !!! et surtout, merci d'avoir pris le temps d'expliquer le raisonnement !
    Je n'ai effectivement pas eu l'intelligence de le mettre de façon plus lisible, comme tu l'as fait.
    Mais tes explications me sont très utiles pour comprendre comment chercher les données.
    Encore merci, je peux enfin la finir ! ;)



  • @Ayckinn De rien, tu étais sur la bonne voie. Il ne te manquais pas grand-chose ;)



  • @KroMignon
    Pour être honnête, même si j'avais réussi, j'aurais pas réellement compris comment j'ai fait, j'ai mixé un peu tout ce que je trouvais sur Internet et je faisais des tests..
    C'est en ça que ton explication vaut plus chère que la solution, parce que maintenant, je sais COMMENT réfléchir ;)



  • Avec mes excuses... Je reviens car je n'arrive pas a récupérer les valeurs dans [name] par exemple, [main][temp] ou [wind][speed].

    J'ai essayé plusieurs choses avant de reposter en me basant sur la solution donnée ci-dessus, mais comme ce ne sont pas des tables, je n'arrive pas a récupérer les valeurs.
    Je pensais avoir compris le principe, apparemment je suis plus truffe que je le croyais.

    1er test

    JSON_object = loadJSONFile.object()["wind"].toObject();
    JSON_value = JSON_object["speed"].toString();
    

    2eme test

    JSON_array = loadJSONFile.object()["main"].toArray();
    JSON_object = JSON_array[0].toObject();
    JSON_value = JSON_object["temp"].toString();
    

    Ca me semblait tellement simple avec les explications...



  • @Ayckinn said in Récupérer données JSON d'une API météo:

    Je pensais avoir compris le principe, apparemment je suis plus truffe que je le croyais.

    1er test
    JSON_object = loadJSONFile.object()["wind"].toObject();
    JSON_value = JSON_object["speed"].toString();

    Le parser JSON n'est pas super sympa, j'en ai déjà fait l'amer expérience.
    Le problème ici, c'est que la valeur speed n'est pas une chaîne de caractères mais un nombre.
    En l’occurrence un nombre entier donc il faut utiliser toInt() ou toDouble()

    Donc pour lire la valeur:

    auto jsonRoot = loadJSONFile.object();
    auto jsonWind = jsRoot["wind"].toObject();
    qDebug() << "Speed is" << jsonWind ["speed"].toInt(); 
    qDebug() << "Speed is" << jsonWind ["speed"].toDouble(); 
    

    2eme test
    JSON_array = loadJSONFile.object()["main"].toArray();
    JSON_object = JSON_array[0].toObject();
    JSON_value = JSON_object["temp"].toString();

    Ca me semblait tellement simple avec les explications...

    Idem ici:

    auto jsonRoot = loadJSONFile.object();
    auto jsonMain = jsRoot["main"].toObject();
    qDebug() << "Temperatur is" << jsonMain["temp"].toDouble(); 
    


  • @KroMignon
    Je confirme... Je ne pensais pas que ce serait aussi complexe. En tout cas, merci beaucoup d'avoir encore une fois, pris le temps de me répondre et de m'expliquer surtout.

    Me reste 2 questions et promis, je te laisse tranquille ;) J'aurais toutes les infos dont j'ai besoin

    1. A quoi sert 'auto' ?
    2. Comment je peux récupérer la valeur de "name" ? Car ca ne se situe pas entre accolades et tient sur une seule ligne.


  • @Ayckinn said in Récupérer données JSON d'une API météo:

    Me reste 2 questions et promis, je te laisse tranquille ;) J'aurais toutes les infos dont j'ai besoin

    A quoi sert 'auto' ?

    auto c'est pour les fainéants comme moi qui ne veule pas réécrire le type de la variable qu'ils sont entrain de créer:

    Comment je peux récupérer la valeur de "name" ? Car ca ne se situe pas entre accolades et tient sur une seule ligne.

    Les accolades {}, c'est pour définir un nouvel objet et les crochets [] c'est pour définir une table.
    S'il n'y a ni l'un ni l'autre c'est que c'est une valeur, ici en l’occurrence une chaîne de caractères ;)

    auto jsonRoot = loadJSONFile.object(); // idem que QJsonObject jsonRoot = loadJSONFile.object();
    qDebug() << "name is" << jsonRoot["name"].toString();
    


  • @KroMignon
    Bon ben voilà, j'ai tout ce qu'il me faut cette fois... Comme promis, je te laisse tranquille !! :)
    ENORME merci a toi ! Je ne sais pas où tu habites mais je t'aurais bien offert une bière ^^
    Bonne journée :)



  • @Ayckinn said in Récupérer données JSON d'une API météo:

    Bonne journée :)

    Merci, je boirai une p'tite bière à ta santé ce soir ;)

    Pour info, j'habite en Allemagne tout près de Strasbourg.



  • @KroMignon

    Avec plaisir, je ferais de même, parce que là, t'as vraiment assuré :)

    Ah dommage, t'es un peu loin, je suis dans le sud de la France


  • Lifetime Qt Champion

    À tout hasard, pour une expérience plus "naturelle" de manipulation de données JSON, la librairie C++ json de nlohmann est très sympa à utiliser et facile à intégrer dans un projet.



  • @SGaist Merci pour l'info.

    J'étais déjà tombé dessus, mais comme j'ai une application qui utilise un vieux compilateur C++ pas entièrement C++11 compatible (WindowsXP oblige!!!!), je ne pouvais pas l'utiliser :(


  • Lifetime Qt Champion

    @KroMignon said in Récupérer données JSON d'une API météo:

    WindowsXP oblige!!!!

    Je compatis


Log in to reply