X

Carte du Vendée Globe en Direct : PostGIS et requêtes spatiales

N’avez-vous pas envie de vous échapper vers de lointains horizons? Qui plus est dans le contexte actuel de restrictions de déplacement? La course du Vendée Globe 2020 « tombe à point nommée » pour s’évader à travers mers et océans du monde. Même si c’est virtuel, accompagner les navigateurs solitaires de cette course de voiliers procure des centaines d’idées de voyages et d’aventures. Hugo d’Agrarian Systems Consulting m’a soufflé l’idée de réaliser la carte du Vendée Globe en direct.

Comme pour la carte du coronavirus Covid-19 en direct, l’enjeu principal est de trouver une source de données fiables mises à jour en temps réel. Ensuite, la lecture programmée et automatisée des données permet leur bancarisation dans un Système de Gestion de Bases de Données (SGBD). Enfin, les positions géographiques des navigateurs et les routes de leur course sont affichées sur la carte en direct. La cartographie du Vendée Globe 2020 montre le classement des skippers ainsi que d’autres informations comme la vitesse et le cap du voilier. Ce dernier élément nous servira pour la représentation cartographique des voiliers en forme de flèche orientée dans PostgreSQL.

Dans cet article, on se focalise sur la bancarisation des données de la course nautique avec la lecture des sources des informations géographiques et la construction de la base de données. Un prochain article sera dédié au développement de l’interface de webmapping du Vendée Globe 2020.

I. Présentation du Vendée Globe 2020

Le Vendée Globe est une course de voiliers monocoques autour du monde qui se déroule tous les quatre ans. Cette course a été créée en 1989 par le navigateur Philippe Jeantot avec l’appui du Conseil département de Vendée (figure 1).

Figure 1 : Logo du Vendée Globe

Concernant le parcours du Vendée Globe, le départ se situe au large des Sables-d’Olonne. L’objectif est faire le tour de l’Antarctique en laissant à bâbord les trois Caps de Bonne Espérance en Afrique du Sud, de Leeuwin en Australie et du Cap Horn sur l’Île d’Horn au Chili (figure 2). On estime à environs 21 638 milles soient 40 075 km la distance totale à parcourir.

Figure 2 : Cartographie de la route du Vendée Globe (source : Wikipédia).

II. Carte du Vendée Globe en temps réel

II.1. Source des données géographiques du Vendée Globe

Un site internet est dédié pour le Vendée Globe. On y retrouve une page présentant le classement en temps réel de l’édition 2020 et une cartographie en direct. Sur cette première page, un fichier excel est mis à disposition avec l’ensemble des informations concernant la course et les skippers. Comme le montre la figure 3 ci-dessous, les positions en longitude et latitude des voiliers sont également présents sur le tableur.

Figure 3 : Fichier Excel avec les informations du classement du Vendée Globe.

En outre, l’ensemble de ces informations est mis à jour toutes les 3 heures environs. Par conséquent, on a tous les éléments pour créer une chaîne de traitements de données spatio-temporelles en quasi temps-réel.

II.2. PostGIS : Bancarisation des données géographiques de la course

Dans un premier temps, on construit la table PostgreSQL qui doit accueillir l’ensemble des valeurs attributaires du fichier excell importé. On a le fichier SQL suivant :

CREATE TABLE {nom de la table} -- Table 
(
    gid serial, -- identifiant
    rank integer, -- classement
    nationalite character varying(10),
    skipper character varying(255), -- skipper / bateau
    heure timestamp, -- heure française
    longitude numeric(15,12), -- longitude en degre
    latitude numeric(14,12), -- latitude en degre
    cap_30min integer, -- cap en degre depuis 30 min
    vitesse_30min numeric(4,1), -- vitesse en kts depuis 30 min
    vmg_30min numeric(5,1), -- VMG : Velocity Made Good depuis 30 min = projection du vecteur vitesse sur la route théorique. Ou plus simplement : vitesse de rapprochement au but
    distance_30min numeric(4,1), -- distance parcourue depuis 30 min en nautical miles
    cap_ultimate integer, -- cap en degre depuis le dernier classement
    vitesse_ultimate numeric(5,1), -- vitesse en kts depuis le dernier classement
    vmg_ultimate numeric(5,1), -- VMG : Velocity Made Good depuis le dernier classement = projection du vecteur vitesse sur la route théorique. Ou plus simplement : vitesse de rapprochement au but
    distance_ultimate numeric(4,1), -- distance parcourue depuis le dernier classement en nautical miles
    cap_24h integer, -- cap en degre depuis 24h
    vitesse_24h numeric(5,1), -- vitesse en kts depuis 24h
    vmg_24h numeric(4,1), -- VMG : Velocity Made Good depuis 24h = projection du vecteur vitesse sur la route théorique. Ou plus simplement : vitesse de rapprochement au but
    distance_24h numeric(4,1), -- distance parcourue depuis 24h en nautical miles
    dtf numeric(50,1), -- Distance To Finish = Distance théorique la plus courte pour rejoindre l'arrivée
    dtl numeric(50,1), -- Distance To Leader = différence de distance au but avec le premier au classement
    geom geometry(Point,4326),
    CONSTRAINT {nom de la table}_pkey PRIMARY KEY (gid)
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE {nom de la table}
    OWNER to {nom de l'utilisateur};
CREATE INDEX {nom de l'index} ON {nom de la table} USING GIST(geom);

Quelques remarques sur la structure de la table SQL :

  • la colonne gid désigne l’identifiant de la table. Son type est SERIAL qui permet de créer une séquence d’entier auto-incrémenté. On lui assigne également une contrainte de clé primaire pour garantir l’unicité des valeurs enregistrées;
  • le champ heure : la colonne Heure FR du fichier excel n’indique ni le jour ni le mois du relevé du classement. Il est donc important lors de l’INSERT dans la table de formater la date;
  • la longitude et la latitude : sur le fichier excel, les coordonnées géographiques sont en Degré Minute Seconde (DMS). On les transformera en Degré Décimal (DD) à l’aide d’une fonction;
  • la colonne de géométrie geom est de type Point en WGS84/EPSG:4326 construit sur les coordonnées géographiques (en DD) des positions des navigateurs. On créé un index sur cette colonne afin de favoriser les requêtes de tri et de hachage.

II.3. Des requêtes spatiales pour la représentation cartographique du Vendée Globe en direct

II.3.1. Les fonctions PostGIS utilisées

Dans cette section, on se focalise sur le contenu et la forme des informations que l’on souhaite afficher sur la carte du Vendée Globe en direct. Deux éléments de la course nous paraissent essentiels : la route parcourue par chaque navigateur et les dernières positions des voiliers enregistrées. Pour cela, on construit les requêtes spatiales nécessaires sur la base des données géographiques brutes. Ainsi on utilise sept fonctions PostGIS. Trois fonctions sont destinées à construire des géométries :

  • ST_MakePoint : construit une géométrie ponctuelle à partir de coordonnées géographiques X (longitude) et Y (latitude);
  • ST_MakeLine : construit une ligne à partir de points;
  • ST_MakePolygon : construit un polygone à partir d’une ligne fermée.

Puis, deux fonctions permettent d’accéder à la géométrie :

  • ST_X : retourne la coordonnée X (longitude);
  • ST_Y : retourne la coordonnée Y (latitude).

Enfin, on utilise également deux fonctions éditrices de géométries :

  • ST_Rotate : effectue une opération de rotation de la géométrie (en radians);
  • ST_SetSrid : met à jour la projection spatiale.

II.3.2. Les routes du Vendée Globe par Skipper

Construire les routes parcourues des différents Skippers du Vendée Globe est relativement simple. On sait qu’une route est un objet géographique de type linéaire construit par un ensemble de points. Comme on enregistre toutes les trois heures les positions géographiques ponctuelles des voiliers, il suffit d’agréger l’ensemble des points de la table SQL. la fonction PostGIS st_makeline affecté à l’ensemble des géométries ponctuelles génère une ligne. Enfin, on créé une ligne par skipper en utilisant la clause GROUP BY. La requête ci-dessous est pris en charge dans une vue:

 SELECT st_makeline(geom) AS geom,
    nationalite,
    skipper
   FROM { Nom de la table }
  GROUP BY nationalite, skipper;

Sur l’outil d’administration PgAdmin, le Geometry Viewer montre les différentes routes parcourues par les skippers sur la carte (figure 4).

Figure 4 : Représentation cartographique des parcours des skippers.

II.3.3. Dernières positions géographiques des voiliers en temps réel représentées par des flèches orientées par le cap

Maintenant, on souhaite afficher les dernières positions des navigateurs à l’aide de flèches orientées sur la base du cap pris par le voilier. Alors comment créer une flèche à l’aide de fonctions PostGIS?

Représentation de flèches orientées au Nord

Pour la représentation cartographique, on décide de créer une flèche de type polygonal composée de quatre points. La géométrie de chaque entité enregistrée dans la table constitue le point de base indiquant l’orientation. Alors pour dessiner une flèche avec l’orientation à 0° Nord, on a dans le sens des aiguilles d’une montre :

  1. le point de base avec les coordonnées géographiques X et Y;
  2. le second point possède une longitude X plus grande et une latitude Y plus faible que le point de base. Ici, on choisit d’ajouter 0.5° en longitude et de retirer 1° en latitude;
  3. le troisième point possède la même longitude que le point de base et on retire une plus faible valeur en Y, ici 0.5°, que le second et quatrième point;
  4. le quatrième point à une longitude opposée à celle du second point par rapport au point de base et la même coordonnée Y.

Pour chaque point (de 2 à 4), on extrait donc les coordonnées X et Y de la géométrie avec les fonctions st_x et st_y afin de modifier les positions géographiques de base. Puis on construit le point de ces nouvelles coordonnées avec st_makepoint sans oublier de préciser la projection géographique à l’aide de st_setsrid. Les quatre points agrégés dans un tableau forment une ligne avec st_makeline(ARRAY[]). La requête SQL intermédiaire formant la flèche orientée 0° Nord est la suivante :

 SELECT st_makeline(ARRAY[geom, st_setsrid(st_makepoint(st_x(geom) + 0.5::double precision, st_y(geom) - 1::double precision), 4326), st_setsrid(st_makepoint(st_x(geom), st_y(geom) - 0.5::double precision), 4326), st_setsrid(st_makepoint(st_x(geom) - 0.5::double precision, st_y(geom) - 1::double precision), 4326)]) AS arrow
   FROM { nom de la table };

La figure 5 nous montre le résultat pour de nombreux enregistrements ponctuels sur une cartographie :

Figure 5 : Création de flèches avec PostGIS.
Orientation des flèches selon le cap des voiliers

Ensuite, on s’appuie sur les valeurs attributaires de la colonne cap_30min et les centroïdes des géométries de base pour orienter les flèches. Ainsi, on utilise la fonction PostGIS st_rotate qui permet de réaliser la rotation de la géométrie. Attention, il faut noter que l’angle de rotation pris en charge dans la fonction est en radians. Or, les valeurs enregistrées des caps sont en degrés. On multiplie donc l’angle du cap par pi()/180 pour le convertir en radians. Enfin, pour anticiper la symbologie affectée aux flèches dans la carte du Vendée Globe en direct, on transforme la ligne en polygone avec st_makepolygon. Donc, on ajoute la géométrie du point de base à la ligne pour fermer le polygone. Par conséquent, on a :

SELECT st_makepolygon(st_rotate(st_makeline(ARRAY[geom, st_setsrid(st_makepoint(st_x(geom) + 0.5::double precision, st_y(geom) - 1::double precision), 4326), st_setsrid(st_makepoint(st_x(geom), st_y(geom) - 0.5::double precision), 4326), st_setsrid(st_makepoint(st_x(geom) - 0.5::double precision, st_y(geom) - 1::double precision), 4326), geom]), (- cap_30min)::double precision * (pi() / 180::double precision), st_centroid(geom))) AS arrow
   FROM { nom de la table } ;

Sélection des dernières positions de chaque voilier

Enfin, on sélectionne les dernières positions géographiques de chaque voilier à l’aide d’une sous-requête dans laquelle on retient la dernière date enregistrée. La requête SQL ci-dessous est implémentée dans une vue :

 SELECT t1.heure,
    t1.rank,
    t1.nationalite,
    t1.skipper,
    t1.dtf,
    t1.dtl,
    t1.vitesse_30min,
    t1.cap_30min,
    st_makepolygon(st_rotate(st_makeline(ARRAY[t1.geom, st_setsrid(st_makepoint(st_x(t1.geom) + 0.5::double precision, st_y(t1.geom) - 1::double precision), 4326), st_setsrid(st_makepoint(st_x(t1.geom), st_y(t1.geom) - 0.5::double precision), 4326), st_setsrid(st_makepoint(st_x(t1.geom) - 0.5::double precision, st_y(t1.geom) - 1::double precision), 4326), t1.geom]), (- t1.cap_30min)::double precision * (pi() / 180::double precision), st_centroid(t1.geom))) AS arrow
   FROM { nom de la table } t1
WHERE heure = (SELECT heure FROM { nom de la table } ORDER BY heure DESC LIMIT 1)
  ORDER BY t1.rank;

Les dernières positions géographiques des voiliers orientés selon leur cap sont localisées sur la cartographie du Geometry Viewer (figure 6).

Figure 6 : Carte du Vendée Globe en direct : dernières positions des voiliers en course orientées selon leur cap.
A vos votes!

En conclusion, on a mis en place les requêtes spatiales représentant la route des voiliers ainsi que les dernières localisations des skippers en course orientées selon leur cap. Ensuite, il nous reste à créer l’interface de webmapping pour présenter la carte du Vendée Globe en direct. Pour cette construction et le tutoriel du prochain article qui en découlera, on vous propose deux solutions au choix afin de cartographier les voiliers :

  1. Soit, une prise en charge des données géographiques issues de la base de données PostgreSQL avec GeoServer. Cela induit donc le style SLD des polygones en forme de flèches et la diffusion des positions des skippers en temps réel en WFS / WMS. L’interface cartographique basée sur OpenLayers chargera le protocole WMS;
  2. Soit, la construction d’une API sur un serveur NodeJS faisant appel aux dernières positions des voiliers en format GeoJSON. Ces derniers objets géographiques seront appelés sur l’interface cartographique construite avec OpenLayers.

Vous pouvez voter pour la solution 1 ou 2 en commentaire!

NB : A l’heure de l’écriture de cet article, le skipper Charlie Dalin est en tête de la course (figure 7). Bon courage à tous les navigateurs pour la suite du Vendée Globe 2020!

Figure 7 : Photographie du bateau du skipper Charlie Dalin (source : France Bleu).
Partager l'article
Florian Delahaye: Passionné de Géomatique

View Comments (13)

Related Post