Utiliser Vue.js pour afficher la météo en un lieu

Objectif: Ce TP a pour but de vous faire découvrir le framework Vue.js pour construire des interfaces Web.

Références :

Dans le TP précédent vous avez travaillé avec l'API OpenWeather. Vous allez à nouveau utiliser celle-ci dans une petite application Web dont l'interface sera construite en utilisant les frameworks Vue.js et Bootstrap.

0. Ma première application Vue - Prise en main des outils

  1. Téléchargez le fichier MyFirstVueApp.zip que vous décompresserez dans le répertoire AWA/TP03

  2. Ouvrez le dossier MyFirstVueApp dans VSCode et ouvrez avec LiveServer le fichier index.html

  3. Vérifiez que l'interaction avec la page fonctionne correctement (lorsque vous modifiez le texte dans le champ de saisie, le texte au dessus est lui aussi modifié.

    la page Hello Vue !
  4. Installer l'outil Vue.js devtools dans votre navigateur et à l'aide celui-ci modifiez le message.

1. Recherche de lieux à partir d'un toponyme

Vous allez dans un premier temps construire une première version simple de l'application qui en utilisant l' API de géocodage d'OpenWeather permet de retrouver pour un toponyme (nom de lieu) donné l'ensemble des lieux répondant à ce nom connus dans la base de données d'Open Weather et des les afficher sous la forme d'un tableau comme indiqué sur la figure ci-dessous.

Recherche de lieux correspondant à un toponyme
Recherche de lieux correspondant à un toponyme.
  1. Créez un répertoire TP03

  2. Dans celui-ci créez un fichier index.hml et recopiez dans celui-ci le contenu suivant

    <!DOCTYPE html>
    <html>
    
    <head>
        <title>Vue Météo</title>
        <link rel="icon" type="image/png" href="images/logoIcon.png">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" 
              rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" 
              crossorigin="anonymous"">
    
    </head>
    
    <body>
    
        <div class="container">
            <h1>Vue sur la météo <img src="images/logo.png" alt=""></h1>
            <form>
                <div class="mb-3">
                    <input id="nomLieu" class="form-control" type="text" placeholder="Nom du lieu">
                    <div id="nomLieuHelp" class="form-text">Entrez un toponyme et trouvez le(s) lieu(x) correspondant
                        avec l'API de gécodage d'openWeather</div>
                </div>
                <button type="submit" class="btn btn-primary">Rechercher</button>
            </form>
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" 
              integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" 
              crossorigin="anonymous"></script>
    </body>
    
    </html>
    
                                    

    Ce code HTML permet de définir le champ de saisie du nom de lieu et le bouton de recherche avec une mise en forme effectuée avec Bootstrap 5.

  3. Toujours dans le répertoire TP03, créez un sous répertoire images dans lequel vous enregistrerez les images suivantes

       et  

    Pour enregister une image faire un clic droit sur l'image et choisir l'item Enregistrer l'image sous... dans le menu contextuel. Vous nommerez la première image logo.png et la deuxième logoIcon.png

  4. Toujours dans le répertoire TP03, créez un sous répertorie js et dans celui un fichier weatherUtils.js dabs lequel vous recopierez le code ci dessous.

    const apiKey = "...."; //Api key for open-weather  A REMPLACER par votre clé d'API
    const geocodageURL = "https://api.openweathermap.org/geo/1.0/direct?limit=5&appid=" + apiKey + "&q="; // API de geocodage openWeather
    const currentWeatherAPIUrl = `https://api.openweathermap.org/data/2.5/weather?appid=${apiKey}&lang=fr&units=metric&`;
    
    
    
    /**
     * Récupère les lieux correspondant à un toponyme donné (nom de lieu)
     * @param {string} nomLieu le nom du lieu à chercher
     * @returns un tableau d'objets Location. Un objet Location possède les propriétés suivantes
     *   - name : nom du lieu
     *   - lat : latitude du lieu
     *   - lon : longitude du lieu
     *   - country : le pays du lieu
     */
    export async function getLocations(nomLieu) {
        let response = await fetch(geocodageURL + encodeURI(nomLieu));
        if (response.ok) {
            let data = await response.json();
    
            let locations = [];
            for (let location of data) {
                // chacun des lieux trouvé est stocké dans le tableau locations
                // locations.push({
                //     name: location.name,
                //     lat: location.lat,
                //     lon: location.lon,
                //     country: location.country,
                //     selected: false,
                // });
                // code équivalant en utilisant une instruction de desctructuration
                let { name, lat, lon, country } = location;
                locations.push({ name, lat, lon, country, selected: false });
            }
            return locations;
        } else {
            throw new Error(`Erreur géolocalisation :   ${response.status} ${response.statusText}`);
        }
    }
    
    /**
     * Récupère les conditions météo pour un lieu donné
     * @param {Location} objet décrivant la localisation du lieu (voir fonction getLocation)
     * @returns un objet décrivant la météo en ce lieu avec les propriétés suivantes : 
     *   - temperature : number    la témperature en ce lieu
     *   - description : string    la description textuelle des conditions météo 
     *   - iconURL : string        url de l'icone openweather symbolisant les conditions météo 
     *   - jour : string           chaîne de caractères donnant le jour (au format textuel)
     *   - heure : string          chaîne de caractères donnant l'heure (au format texte)
     */
    export async function getMeteo(location) {
        let responseHTTP = await fetch(currentWeatherAPIUrl + `&lat=${location.lat}&lon=${location.lon}`);
        if (responseHTTP.ok) {
            let weatherData = await responseHTTP.json();
            // Récupérer les données de température et de description du temps
            const timestamp = weatherData.dt * 1000; // dt est en secondes, on mutiplie par 1000 pour avoir des ms
            const date = new Date(timestamp);
            const dateString = date.toLocaleDateString("fr-FR", {
                day: "numeric",
                month: "short",
                year: "numeric",
            });
            const timeString = date.toLocaleTimeString("fr-FR", {
                hour: "2-digit",
                minute: "2-digit",
                second: "2-digit",
            });
    
            return {
                temperature: weatherData.main.temp,
                description: weatherData.weather[0].description,
                iconURL: "https://openweathermap.org/img/wn/" + weatherData.weather[0].icon + ".png",
                jour: dateString,
                heure: timeString,
            };
        } else {
            throw new Error(`Erreur acquistion météo : ${responseHTTP.status} ${responseHTTP.statusText}`);
        }
    }

    Ce code est un module ESM qui définit deux fonctions que vous pourrez utiliser pour récupérer les informations météorologiques via l'API openweather

    • getLocations() qui permet de trouver la géolocalisation de tous les lieux correspondant à un toponyme donné et répertoriés dans la base de données d'openweather
    • getMeteo() qui permet de récupérer la météo en un lieu donné

  5. Ouvrez la page index.html dans votre navigateur et vérifiez que l'affichage obtenu correspond bien à l'image ci-dessous.

    La page d'accueil de l'application
    La page d'accueil de l'application.
  6. Complétez ce code en utilisant Vue.js (version 3) pour invoquer l'API de géocodage d'OpenWeather lorsque l'utiliseur clique sur le bouton Rechercher et pour afficher le résultat de cette recherche.

    • Si la recherche a été fructueuse (un ou plusieurs lieux géographiques ont été trouvés), une table HTML donnant pour chaque lieu trouvé son nom, le pays correspondant, ses coordonnées géographiques (latitude et longitude) est affichée.

      echec de la recherche
    • Si aucun lieu n'a été trouvé, un message indiquant l'échec de la recherche est affiché.

      echec de la recherche

2. Afficher la météo d'un lieu

1. Modifiez la page précédente pour que lorsque la recherche a abouti (un ou plusieurs lieux ont été trouvés) les conditions météo du premier lieu trouvé soit récupérées via l'API Current Weather de openWeather et affichées en dessous de la table des lieux trouvés. Vous ferez aussi en sorte que ce premier lieu apparaisse comme sélectionné (par exemple vous appliquerez le style bootstrap table-primary à la ligne du tableau correspondant à ce lieu).

affichage des conditions météos

Pour obtenir l'icône correspondant aux conditions météo du lieu voir https://openweathermap.org/weather-conditions

2. Modifiez la page pour que lorsque l'utilisateur clique sur une ligne de la table des résultats celle-ci apparaisse comme sélectionnée et que la météo actuelle du lieu correspondant soit affichée.

affichage des conditions météos du lieu sélectionné

3. Afficher le lieu sélectionné sur une carte

En utilisant une API de webmapping (par exemple Leaflet ou OpenLayer) affichez les lieux trouvés sur une carte.

affichage des lieux sur une carte