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
- II. Carte du Vendée Globe en temps réel
- II.1. Source des données géographiques du Vendée Globe
- II.2. PostGIS : Bancarisation des données géographiques de la course
- 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
- II.3.2. Les routes du Vendée Globe par Skipper
- 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
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).
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.
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.
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).
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 :
- le point de base avec les coordonnées géographiques X et Y;
- 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;
- 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;
- 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 :
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).
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 :
- 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;
- 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!
View Comments (13)
Super article ....
Mettez vous une routine pour récupérer le fichier excel?
Je vote pour l'option 2
Merci et bonne continuation
Bonjour Feron,
Je vous remercie pour votre retour.
Sur le serveur Debian, un crontab déclenche un shell toutes les heures qui vérifie si le téléchargement du fichier excel est possible. Si c'est le cas, on convertit le fichier en csv puis les informations du tableur sont traitées et bancarisées.
Bonne continuation à vous également,
FD
Bonjour, très bon article.
Et ma question est la même que FERON, comment automatiser la lecture du fichier Excel ?
Je vote pour l'option 2
Merci
Notre site : http://www.terrevirtuelle.org/
est en mise à jour en ce moment.
Bonjour Lithops,
Je vous remercie pour votre vote. J'ai répondu ci-dessus à Feron.
Terre Virtuelle est basée dans quelle ville?
FD
crontab, merci pour l'info.
Notre association est basée à Brest, l'application en développement est NaVisu4D, notre site :
http://www.terrevirtuelle.org/Navisu4D/
super article , c'est intéressent pour moi pcq je suis en master Informatique appliqué au SIG
Merci Luc. Bonne continuation pour la suite de vos études.
FD
Option 2 !
Merci pour le vote.
Intéressant, merci !
Et on peut également jouer au Vendée Globe virtuel (ainsi qu'à d'autres courses de voiliers) sur, notamment:
http://www.regattagame.net
(construit avec mapserver et openlayers)
Merci pour l'info.
Option 2, si elle n'est pas déjà faites, puisque la course est finie.
Merci, suis intéressé.
Hello Florian,
nice article!
Is the downloaded and accumulated data available? I would like to plot routes in the Spilhaus projection.
Cheers,
Bjoern