Les APIs

Une API (Application Programming Interface) est un point d’accès mis à disposition par un service (site web, administration, application) pour permettre à d’autres programmes de demander et recevoir des données ou le résultat d’une requete.

Dit autrement, une API permet de poser des questions à une base de données à distance, d’effectuer des traitements ou des opérations à distance, et d’en recevoir les réponses automatiquement.

Le résultat est généralement renvoyé au format JSON.

Voyons quelques exemples.

Altimétrie

Le service Géoplateforme de calcul altimétrique de l’IGN est disponible à l’adresse suivante : https://geoservices.ign.fr/documentation/services/services-geoplateforme/altimetrie. Il s’appuie sur des ressources altimétriques pour fournir des altitudes. l’API permet de d’obtenir :

  • l’altitude d’un ou de plusieurs points ;
  • un profil altimétrique le long d’une courbe.

⚠️ Le nombre de requètes est limité à 5/s.

Toute la documentation est ici

  • Récupérer l’altitude d’un point

Voici les coordonnées de Montmartre : [48.88685856740631, 2.3430894611004986]

https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=2.3430894611004986&lat=48.88685856740631&resource=ign_rge_alti_wld

❓ Quelle est l’altitude de ce point ?

Essayez à présent :

https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=2.3430894611004986&lat=48.88685856740631&resource=ign_lidar_hd_mnx_multi_wld

❓ Quelle est l’altitude de ce point ?

Pour voir les différentes ressources possibles, vous pouvez taper ceci

https://data.geopf.fr/altimetrie/resources
https://data.geopf.fr/altimetrie/resources/ign_rge_alti_wld
  • Récupérer l’altitude de plusieurs points

POur récupérer l’altitude de plusieurs points, on peut passer à l’utl plusieurs coordonnées séparées par un caractere spécial.

https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=1.48|1.49&lat=43.54|43.55&resource=ign_rge_alti_wld&delimiter=|&indent=false&measures=false&zonly=false

La signification de tous les parametres sont précisés sur cette page

En JavaScript, on peut généralement utiliser une API avec les fonctions fetch() ou d3.json().

⚠️ Ce sont des fonctions asysnchrones.

const url =
    "https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=1.48|1.49&lat=43.54|43.55&resource=ign_rge_alti_wld&delimiter=|";

async function main() {
  const response = await fetch(url);
  const data = await response.json();
  console.log(data);
}
main();

On peut aussi utiliser le JavasCript pour construire l’url. Voici un exemple.

// Voici une liste de lieux
const lieux = [
  { nom: "Mont Blanc", lat: 45.8326, lon: 6.8652 },
  { nom: "Barre des Écrins", lat: 44.9225, lon: 6.3619 },
  { nom: "Mont Ventoux", lat: 44.1740, lon: 5.2780 },
  { nom: "Pic du Midi de Bigorre", lat: 42.9368, lon: 0.1428 },
  { nom: "Puy de Sancy", lat: 45.5289, lon: 2.8083 },
  { nom: "Pic de Canigou", lat: 42.5183, lon: 2.4567 },
  { nom: "Grand Ballon", lat: 47.9043, lon: 7.0982 },
  { nom: "Mont Aigoual", lat: 44.1180, lon: 3.5805 },
  { nom: "Pic du Midi d’Ossau", lat: 42.8000, lon: -0.4420 },
  { nom: "Mont Lozère", lat: 44.4236, lon: 3.7350 }
];

// On récupère les latitudes
const latitudes = lieux.map(lieu => lieu.lat).join("|");
console.log(latitudes)

// On récupère les longitudes
const longitudes = lieux.map(lieu => lieu.lon).join("|");
console.log(longitudes)

// On construit l'url
const url = "https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=" + longitudes + "&lat=" + latitudes + "&resource=ign_rge_alti_wld&delimiter=|"
console.log(url)

// Lancer la requete avec fetch

// Récupérer les resultats

On aurait pu aussi faire comme ceci avec les backticks (`) [ALTGR+7]. Cette solution est plus claire.

const url = `https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=${$longitudes}&lat=${$latitudes}&resource=ign_rge_alti_wld&delimiter=|`

Bien sur, on peut profiter des capacités de l’environnement web pour construire quelque chose de plus agréable à utiliser.

  <label for="lieux">Choisissez un lieu :</label>
  <select id="lieux" name="lieux">
    <option disabled selected>-- Choisissez un sommet --</option>
  </select>

  <div id="resultat"></div>
const lieux = [
  { nom: "Mont Blanc", lat: 45.8326, lon: 6.8652 },
  { nom: "Barre des Écrins", lat: 44.9225, lon: 6.3619 },
  { nom: "Mont Ventoux", lat: 44.1740, lon: 5.2780 },
  { nom: "Pic du Midi de Bigorre", lat: 42.9368, lon: 0.1428 },
  { nom: "Puy de Sancy", lat: 45.5289, lon: 2.8083 },
  { nom: "Pic de Canigou", lat: 42.5183, lon: 2.4567 },
  { nom: "Grand Ballon", lat: 47.9043, lon: 7.0982 },
  { nom: "Mont Aigoual", lat: 44.1180, lon: 3.5805 },
  { nom: "Pic du Midi d’Ossau", lat: 42.8000, lon: -0.4420 },
  { nom: "Mont Lozère", lat: 44.4236, lon: 3.7350 }
];

// On remplit la liste déroulante
const select = document.querySelector("#lieux");
lieux.forEach((lieu) => {
  const option = document.createElement("option");
  option.textContent = lieu.nom;
  option.value = lieu.nom;
  select.appendChild(option);
});

// On crée la fonction de requete
async function getdata(lieu) {
  const coordonnees = lieux.find((d) => d.nom == lieu);
  const lat = coordonnees.lat;
  const lon = coordonnees.lon;
  const url = `https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=${lon}&lat=${lat}&resource=ign_rge_alti_wld`;

  console.log(url)

  // On execute la requete et on récupère le résultat
  const response = await fetch(url);
  const data = await response.json();

  // On met en forme la réponse
  const altitude = data.elevations[0].z;
  const str = `L'altitude est de ${altitude} metres`;
  // On l'affiche dans le div #resultat
  document.querySelector("#resultat").textContent = str;
}

// On appelle la fonction à chaque fois qu'on selectionne un lieu dans la liste

select.addEventListener("change", () => {
  getdata(select.value);
});
  • Calculer un profil altimétrique

Ce calcul permet d’obtenir un profil en long. Il est accessible via l’URL suivante : https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevationLine.{format}

La requête elevationLine a les mêmes caractéristiques que la requête elevation, avec en supplément :

  • profile_mode : simple ou accurate
  • sampling : une valeur entre 2 et 5000

Exemple de requete :

https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevationLine.json?lon=1.48|1.49&lat=43.54|43.55&resource=ign_rge_alti_wld&delimiter=|&indent=true&measures=false&profile_mode=simple&sampling=4

Essayons de visualiser ce profil en long avec leaflet

<!-- Import de la bibliothèque et du css-->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<div id="map"></div>
// Création de la requete
const bourgdoisans = [45.06330084181238, 6.024127804909032];
const alpeshuez = [45.09033628569288, 6.0704267327131936];
const sample = 20;
const url = `https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevationLine.json?lon=${bourgdoisans[1]}|${alpeshuez[1]}&lat=${bourgdoisans[0]}|${alpeshuez[0]}&resource=ign_rge_alti_wld&delimiter=|&indent=true&measures=false&profile_mode=simple&sampling=${sample}`;

// Crétaion de la fonction
async function main() {
  // Execution de la requte
  const response = await fetch(url);
  const data = await response.json();
  // Cartographie
  const map = L.map("map");
  map.setView([45.08, 6.05], 13);
  const tiles = L.tileLayer(
    "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
    {
      attribution: "© OpenStreetMap",
    },
  ).addTo(map);
  data.elevations.forEach((p) => {
    console.log(p);
    L.marker([p.lat, p.lon]).addTo(map).bindPopup(`Altitude : ${p.z} m`);
  });
}
// Appel de la fonction
main();
#map {
    height: 500px;
}

Il est aussi possible de visualiser ce profil sur un graphique. Voici un apperçu. Nous verrons cela plus en détail dans la partie dataviz.

<div id="chart"></div>
import * as Plot from "https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6/+esm";

// Création de la requete
const bourgdoisans = [45.06330084181238, 6.024127804909032];
const alpeshuez = [45.09033628569288, 6.0704267327131936];
const sample = 20;
const url = `https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevationLine.json?lon=${bourgdoisans[1]}|${alpeshuez[1]}&lat=${bourgdoisans[0]}|${alpeshuez[0]}&resource=ign_rge_alti_wld&delimiter=|&indent=true&measures=false&profile_mode=simple&sampling=${sample}`;

// Crétaion de la fonction
async function main() {
  // Execution de la requte
  const response = await fetch(url);
  const data = await response.json();

  const altitudes = data.elevations.map((d, i) => ({ x: i, y: d.z }));
  const chart = Plot.plot({
    marks: [
      Plot.line(altitudes, { x: "x", y: "y" }), // ligne
      Plot.dot(altitudes, { x: "x", y: "y" }), // points
    ],
    x: { label: "Point le long du profil" },
    y: { label: "Altitude (m)" },
    width: 600,
    height: 300,
  });

  document.getElementById("chart").appendChild(chart);
}
// Appel de la fonction
main();
Exercice

Choisissez deux autres lieux et représentez le profil

Géocodage

Le géocodage est le processus de transformation d’informations localisables en coordonnées géographiques (latitude et longitude). Il existe différents services. EN France, on utilisera L’API de géocodage de la Géoplateforme.

L’API de géocodage de la Géoplateforme a pour but de fournir des coordonnées à partir d’une adresse ou d’une parcelle cadastrale (ou à l’inverse de fournir le localisant le plus proche à partir de coordonnées). Elle s’appuie sur des données BAN, BD TOPO® et Parcellaire Express (PCI).

Il existe 2 types de geocodage (direct et inverse):

  • Le service de géocodage direct permet de fournir les coordonnées géographiques d’une adresse postale, d’un lieu ou de parcelles cadastrales à partir d’une requête HTTP. https://data.geopf.fr/geocodage/search
  • Le service de géocodage inverse a pour but de retourner, à partir d’un ou plusieurs points géographiques indiqués en latitude/longitude, la ou les entités géolocalisées les plus proches correspondantes, parmi les adresses, toponymes, parcelles cadastrales, et/ou unités administratives. https://data.geopf.fr/geocodage/reverse

⚠️ Pour garantir un usage équitable de ce service très sollicité, une limite d’usage est appliquée. Elle est de 50 appels/IP/seconde.

Pour découvrir le service, vous pouvez tapez ceci dans le navigateur web.

https://data.geopf.fr/geocodage/getCapabilities

Pour connaitre les parametres de requete pour le géocodage direct, vous pouvez essayez ceci :

<link
  href="https://unpkg.com/tabulator-tables@5.5.0/dist/css/tabulator.min.css"
  rel="stylesheet"
/>
<script src="https://unpkg.com/tabulator-tables@5.5.0/dist/js/tabulator.min.js"></script>
<div id="table"></div>
async function main() {
  url = "https://data.geopf.fr/geocodage/getCapabilities"
  const response = await fetch(url);
  const data = await response.json();
  console.log(data)
 const table = new Tabulator("#table", {
    data: data.operations[0].parameters,
    layout: "fitColumns", 
          columns: [
        { title: "Nom", field: "name", sorter: "string" },
        { title: "description", field: "description", sorter: "string" },
      ],
    });
}
// Appel de la fonction
main();

Ou simplement regarder cette page : https://data.geopf.fr/geocodage/openapi

Essayeons de voir comment ca marche requete.

https://data.geopf.fr/geocodage/search?q=20 rue de Tolbiac Paris&returntruegeometry=false&limit=1

et

https://data.geopf.fr/geocodage/search?q=20 rue de Tolbiac Paris&returntruegeometry=true&limit=1

On peut rapidemment crééer une petite application.

<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<form id="geocode-form">
  <div>
    Adresse : <input type="text" id="adresse"/>
    <input type="submit" value="Géocoder" />
  </div>
</form>
<div id="resultat"></div>
<div id="map"></div>
#map {
    height: 500px;
}
const form = document.querySelector("#geocode-form");
form.addEventListener("submit", function (event) {
  event.preventDefault(); // Empêche le rechargement de la page
  const q = document.querySelector("#adresse").value;
  drawmap(q);
});

async function drawmap(q) {
  const url = `https://data.geopf.fr/geocodage/search?q=${q}&returntruegeometry=false&limit=1`;
  const response = await fetch(url);
  const data = await response.json();
  // Resultat de le requette
  console.log(data);

  // Adresse trouvée
  const find = data.features[0].properties.label;
  // Coordonnées
  const coords = data.features[0].geometry.coordinates.toReversed();

  // Affichage de l'adresse trouvée
  document.querySelector("#resultat").textContent = "Adresse trouvée : " + find;
  // Creation de la carte
  const map = L.map("map"); // L designe la bibliothèque leaflet. La fonction map crée une carte vide
  // Position et zoom
  map.setView(coords, 13);

  // Ajout d'une couche de tuiles raster
  const tiles = L.tileLayer(
    "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
    {
      attribution: "© OpenStreetMap",
    },
  ).addTo(map);

  L.marker(coords).addTo(map);
}

NB : L’API de géocodage de la Géoplateforme ne permet de faire du géocodage qu’en France. Mais, il existe d’autres API de géocodages pour le Monde entier. Citons-en deux : Nominatim et Photon, deux services de géocodage (direct et inverse) basés sur les données d’OpenStreetMap

Essayons :

https://nominatim.openstreetmap.org/search?q=Caracas&format=json

ou

https://photon.komoot.io/api/?q=Caracas

Météo

Il existe pluseurs API permetant de récupérer la météo. La pluport nécéssitent une clé d’utilisation.

Open-Meteo est une API météo open source qui offre un accès gratuit pour un usage non commercial (sous licence CC BY 4.0)). Aucune clé API n’est requise. Open-Meteo utilise les prévisions météorologiques open data fournies par les services météorologiques nationaux. Comme beaucoup d’autres API météorologiques, Open-Meteo intègre des modèles météorologiques locaux et mondiaux à haute résolution. Contrairement à d’autres API météorologiques, Open-Meteo offre un accès complet à son code source, et toutes les sources de données sont répertoriées ouvertement, en créditant les services météorologiques nationaux pour leur travail.

L’API est accessible ici : https://open-meteo.com/. La documentation est ici https://open-meteo.com/en/docs.

Commençons par taper cette requete dans le navigateur web pour connaitre la meteo actuelle.

https://api.open-meteo.com/v1/forecast?latitude=48.8566&longitude=2.3522&current_weather=true&timezone=Europe/Paris

Ou la prévision quotidienne sur 16 jours

https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&hourly=temperature_2m&forecast_days=16

Tous les parametres sont expliqués ici : https://open-meteo.com/en/docs.

Exercice

Créez une requete pour récupérer les prévisions de précipitation heure par heure

En JavaSCript, on peut donc s’ammuser à faire ceci :

<div id="chart"></div>
import * as Plot from "https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6/+esm";

const paris = [48.8534, 2.3488];
const url = `https://api.open-meteo.com/v1/forecast?latitude=${paris[0]}&longitude=${paris[1]}&hourly=rain&timezone=Europe%2FLondon&forecast_days=16`;

async function meteo() {
  // Execution de la requete
  const response = await fetch(url);
  const data = await response.json();

  // Mise en forme des données
  const rain = data.hourly.time.map((d, i) => ({
    time: new Date(d),
    rain: data.hourly.rain[i],
  }));
  // Création du diagramme en barres
  const myPlot = Plot.plot({
    width: 600,
    height: 400,
    x: { label: "Jours" },
    y: { label: "Précipitations (mm)" },
    marks: [
      Plot.rectY(rain, {
        x: "time",
        y: "rain",
        interval: "hour",
        fill: "steelblue",
      }),
      Plot.ruleY([0]),
    ],
  });
  // On ajoute le plot dans la page
  document.querySelector("#chart").append(myPlot);
}

meteo();

Osrm

OSRM (pour Open Source Routing Machine) est un moteur de calcul d’itinéraires open source, très performant, basé sur les données d’OpenStreetMap. Il permet de calculer des trajets, des distances et des durées de parcours pour différents modes de transport (voiture, vélo, piéton, etc.), un peu comme Google Maps, mais en local ou sur un serveur privé. OSRM est dosponible à l’adresse suivante : https://project-osrm.org.

Pour utiliser OSRM, vous pouvez utilisez différentes services (instances d’OSRM). Chacune s’appuie sur une version du réseau et propose différents calculs.

  • Serveur de demo OSRM : https://router.project-osrm.org/route (voiture uniquement)
  • Serveur INSEE : https://metric-osrm-backend.lab.sspcloud.fr/ (France. voiture uniquement)
  • Serveur https://routing.openstreetmap.de/ (voiture (routed-car), vélo (routed-bike), à pied (routed-foot))

Pour connaitre les différents paramètres, la documentation est accessible ici : https://project-osrm.org/docs/v5.24.0/api/#

Pour commencer, Essayons de calculer le temps de trajet en voiture entre Fontainebleau et Provins. Tapez ceci dans votre navigateur.

https://router.project-osrm.org/route/v1/car/3.2993092939773567,48.559461541790554;2.7013120786972142,48.40457231624569
  • les coordonnées sont au format longitude,latitude ⚠️
  • https://router.project-osrm.org/route/v1/ correspond au service
  • car correspond au moyen de transport.

❓ Quelle est la distance ?

❓ Quelle est le temps de trajet ?

On peut également ajouter d’autres points. Par exemple, aller de Fontainebleau à Sens en passant par Provins.

  "https://router.project-osrm.org/route/v1/car/2.7013120786972142,48.40457231624569;3.2993092939773567,48.559461541790554;3.2830220159456815,48.198749084774064"

En ajoutant les paramètres ?geometries=geojson&overview=full, on peut récupérer les géométries

https://router.project-osrm.org/route/v1/car/3.2993092939773567,48.559461541790554;2.7013120786972142,48.40457231624569?geometries=geojson&overview=full

Ce qui permet de visualiser le trajet sur une carte.

<!-- Import de la bibliothèque et du css-->
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<div id="duration"></div>
<div id="map"></div>
#map {
    height: 500px;
}
const url =
  "https://router.project-osrm.org/route/v1/car/3.2993092939773567,48.559461541790554;2.7013120786972142,48.40457231624569?geometries=geojson&overview=full";

async function main() {
  // Execution de la requete
  const response = await fetch(url);
  const data = await response.json();

  // Durée
  const duration  = data.routes[0].duration/60
  document.querySelector("#duration").textContent = "Temps : " + duration + " minutes"

  // Création de la carte dans le div #map
  const trace = data.routes[0].geometry;
  const map = L.map("map");
  const tiles = L.tileLayer(
    "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
    {
      attribution: "© OpenStreetMap",
    },
  ).addTo(map);
  const layer = L.geoJSON(trace).addTo(map);
  map.fitBounds(layer.getBounds(), { maxZoom: 18 });
}

main();
Exercice

En vous inspirant de l’exemple ci-dessus, calculez le temps de parcours à velo entre le batiment Olympe de Gouges et l’institut de geographie. Et affichez la carte.

Utilisez le service https://routing.openstreetmap.de/ et le moyen de transport routed-bike

const odg = [48.82675288249501, 2.382689386585041] // ⚠️ lat, long 
const igeo = [48.844837368476384, 2.3426324055721186]  // ⚠️ lat, long 
const url = `https://routing.openstreetmap.de/routed-bike/route/v1/driving/${**lon1**},${**lat1**]};${**lon2**},${**lat2**}?geometries=geojson&overview=full`
async function main() {
 // Executez la requete
 // Recupérer le Resultat
 // Récupérez la trace
 // Affichzez la carte
}
main();

❓ Quelle est la distance ?

❓ Quel est le temps de trajet ?

❓ Quel est le temps de trajet en voiture (routed-car) ? A pied (routed-foot) ?

Combinaisons

En combinant les API, on peut faire des choses interessantes.

<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<div id ="temps"></div>
<div id ="meteo"></div>
<div id="chart"></div>
<div id="map"></div>
#map {
    height: 500px;
}
import * as Plot from "https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6/+esm";
async function main() {
  // 1 - GEOCODAGE

  let url =
    "https://data.geopf.fr/geocodage/search?q=rue%20humbert%20le%20bourg%20d%27oisans&returntruegeometry=true&limit=1";
  let response = await fetch(url);
  let data = await response.json();
  const bourgdoisans = data.features[0].geometry.coordinates;

  url =
    "https://data.geopf.fr/geocodage/search?q=avenue%20du%20rief%20niel%20alpe%20d%27huez&returntruegeometry=true&limit=1";
  response = await fetch(url);
  data = await response.json();
  const alpeshuez = data.features[0].geometry.coordinates;

  // 2 - CALCUL AVEC OSRM (VELO)

  url = `https://routing.openstreetmap.de/routed-bike/route/v1/driving/${bourgdoisans[0]},${bourgdoisans[1]};6.0508,45.07467;${alpeshuez[0]},${alpeshuez[1]}?geometries=geojson&overview=full`;

  response = await fetch(url);
  data = await response.json();
  const trace = data.routes[0].geometry;

  document.getElementById("temps").textContent =
    "Temps de parcours : " +
    Math.round(data.routes[0].duration / 60) +
    " minutes";

  // 3 - CREATION DU PROFIL ALTIMETRIQUE

  const coords = trace.coordinates.filter((_, i) => i % 3 === 0);
  const lon = coords.map((d) => d[0]).join("|");
  const lat = coords.map((d) => d[1]).join("|");
  url = `https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json?lon=${lon}&lat=${lat}&resource=ign_rge_alti_wld&delimiter=|&indent=false&measures=false&zonly=false`;
  response = await fetch(url);
  data = await response.json();
  const altitudes = data.elevations.map((d, i) => ({ x: i, y: d.z }));
  const chart = Plot.plot({
    marks: [
      Plot.line(altitudes, { x: "x", y: "y" }), // ligne
      //Plot.dot(altitudes, { x: "x", y: "y" }), // points
    ],
    x: { label: "Point le long du profil" },
    y: { label: "Altitude (m)" },
    width: 600,
    height: 300,
  });

  document.getElementById("chart").appendChild(chart);

  // 4 - CREATION DE LA CARTE
  const map = L.map("map");
  const tiles = L.tileLayer(
    "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
    {
      attribution: "© OpenStreetMap",
    },
  ).addTo(map);
  const layer = L.geoJSON(trace).addTo(map);
  map.fitBounds(layer.getBounds(), { maxZoom: 18 });

  // 5 - RECUPERATION DE LA METEO AU SOMMET
  url = `https://api.open-meteo.com/v1/forecast?latitude=${alpeshuez[1]}&longitude=${alpeshuez[0]}&&current_weather=true&timezone=Europe%2FLondon`;
  response = await fetch(url);
  data = await response.json();
  document.getElementById("meteo").textContent =
    "Il fait " + data.current_weather.temperature + " °C au sommet";
}

main();

⚠️ Problème : OSRM ne prend pas en compte la pente dans le temps de calcul, ce qui est problématique. Dans notre exemple, le temps ets le même en montée et en descente. Mais il existe d’autres engins de routage qui la prennent en compte la pente, comme valhalla. Si vous voulez tester, la documention est disponible ici. https://valhalla.github.io/valhalla/.


L’open data

L’idée de l’Open Data naît dans les années 1990, dans le sillage des mouvements pour le logiciel libre et l’accès libre à l’information scientifique. Mais c’est au tournant des années 2000 que le concept prend de l’ampleur.

2005 : le Royaume-Uni lance le portail data.gov.uk, un des premiers sites publics de données ouvertes.

2007 : à Sebastopol (Californie), une réunion entre militants de la transparence et développeurs formule les principes de l’Open Data : données complètes, primaires, lisibles par machine, libres de droit…

2009 : les États-Unis créent le portail data.gov sur impulsion d’Obama (Open Government Initiative).

2011 : la France ouvre son propre portail de données publiques, data.gouv.fr

En France, le mouvement est porté par des collectivités locales (comme Paris, Rennes, Nantes) et l’État. La loi pour une République numérique (2016) renforce l’obligation d’ouverture des données publiques.

Il existe des API pour accéder aux données publiques.

Sur le site de la mairie de Paris, de nombreux jeux de données sont également disponibles à travers une API qui permet de requeter toutes les dounnées ouvertes de la ville.

Le site est disponible ici : https://opendata.paris.fr/explore

Par exemple, regardons la localisation des stations de Vélib.

https://opendata.paris.fr/explore/dataset/velib-emplacement-des-stations/information/

Il y en a 1459.

Tapez cette URL dans la barre de votre navigateur :

https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-emplacement-des-stations/records

On obtient le résultat de la requete au format JSON. Malheureusemeent, le nombre de résultat est limité à 100. Heureusement, il y a le parametre offset. On fait une boucle et hop.

async function getAllStations() {
  const allStations = [];
  let offset = 0;
  const limit = 100;
  let totalCount = Infinity;

  while (offset < totalCount) {
    const url = `https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-emplacement-des-stations/records?limit=${limit}&offset=${offset}`;
    const response = await fetch(url);
    const data = await response.json();
    allStations.push(...data.results);
    totalCount = data.total_count || allStations.length; // total_count est fourni par l'API
    offset += limit;
  }
  console.log(allStations);
  console.log(allStations.length);
}

getAllStations();

Pour vous faciliter la vie, j’ai créé une petite fonction fetchOpenDataParis() qui permet de récupérer les données et de récupérer les résultats au format geoJSON.

// Modules
import { fetchOpenDataParis } from "https://cdn.jsdelivr.net/gh/neocarto/Webmapping@main/gist/fetchOpenDataParis.js";

// Fonction fetch
async function main() {
  const poi = await fetchOpenDataParis("velib-emplacement-des-stations");
  console.log(poi)
 }

// Appel de la fonction
main();

On peut donc facilement acceder aux données de l’API et les visualiser.

<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<div id="map"></div>
#map {
    height: 500px;
}
// Modules
import { fetchOpenDataParis } from "https://cdn.jsdelivr.net/gh/neocarto/Webmapping@main/gist/fetchOpenDataParis.js";

// Fonction fetch
async function main() {
  const poi = await fetchOpenDataParis("velib-emplacement-des-stations");
  const map = L.map("map");
  L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
    attribution: "© OpenStreetMap",
  }).addTo(map);
  const layer = L.geoJSON(poi).addTo(map);
  map.fitBounds(layer.getBounds());
}
// Appel de la fonction
main();