Rechercher dans le blog

Un mardi, une appli #18 Suivi de l'adoption du vaccin contre la Covid-19 dans le monde

Bonjour et bonne année 2021 à tous ! Aujourd'hui, j'aimerais commencer l'année sur une note positive, je vais donc vous présenter une application que j'ai développée permettant de suivre l'évolution de l'adoption du vaccin dans les pays du monde.
Le code de l'application est retrouvable ici.

I/ L'application

Cette application est très similaire à celle que j'avais fait pour suivre l'évolution de la propagation du Covid-19 au mois de Mars de l'année dernière, dont j'avais déjà fait un article à l'époque.
La carte présente le nombre de vaccinés contre la Covid-19 par centroïde des différents pays qui ont exposés les données des vaccinés. Le slider temporel permet de suivre l'évolution de ce chiffre à travers le temps.
La carte est interactive, vous pouvez sélectionner un géosignet pour vous rendre sur un continent de votre choix. 
Pour chaque pays nous avons la possibilité de cliquer sur les éléments pour ouvrir une popup contenant le nombre de vaccinés à la date choisie du slider temporel, et le taux que ça représente par rapport à la population du pays.

La source des données se trouve ici et est exploitée par le site Our World in Data.

II/ L'aspect technique

Je souhaite aborder dans cette section, les deux principaux points d'intérets que sont le slider temporel qui permettent de faire défiler les données dans le temps, et la symbologie multivariée pour représenter deux attributs :

Le Slider temporel

Le widget TimeSlider simplifie la visualisation des données temporelles dans notre application. Pour qu'il fonctionne il y a plusieurs choses à configurer :

La propriété fullTimeExtent définit la période entière pendant laquelle vous pouvez visualiser vos données sensibles au temps à l'aide du widget TimeSlider

La propriété mode permet de choisir comment visualiser des données temporelles jusqu'à un point dans le temps, à partir d'un point dans le temps, à un instant donné ou à partir de données qui se situent dans une plage de temps. En fonction du mode choisi, le curseur sera différent sur le widget TimeSlider.

La propriété stops définit des emplacements spécifiques sur le TimeSlider où les curseurs se déplacent lorsqu'ils sont manipulés. Vous pouvez définir cette propriété comme un tableau de dates, un nombre d'arrêts régulièrement espacés ou un intervalle de temps spécifique (par exemple, des jours).

Le widget TimeSlider peut être configuré pour appliquer une logique personnalisée chaque fois que le TimeSlider est manipulé en observant sa propriété timeExtent. Par exemple, lorsque la propriété timeExtent du TimeSlider est mise à jour, nous voulons mettre à jour la propriété timeExtent et appliquer un filtre côté client, sur les données issues d'un FeatureLayerViewCSVLayerView ou GeoJSONLayerView. Un filtre sur la vue de la couche peut être utilisé pour filtrer les données qui ne sont pas incluses dans l'intervalle de temps actuel, défini sur le timeSlider

const timeSlider = new TimeSlider({ container: "timeSlider", mode: "instant", view: view }); view.ui.add(timeSlider, "manual"); let timeLayerView; view.whenLayerView(layer).then(function (lv) { timeLayerView = lv; timeSlider.fullTimeExtent = layer.timeInfo.fullTimeExtent; timeSlider.stops = { interval: { value: 1, unit: "days" }, timeExtent: { start: layer.timeInfo.fullTimeExtent.start, end: layer.timeInfo.fullTimeExtent.end } } }); view.ui.add(timeSlider, "manual"); timeSlider.watch("timeExtent", function (value) { // update layer view filter to reflect current timeExtent timeLayerView.filter = { timeExtent: value }; });

Pour lancer automatiquement le TimeSlider lorsque je charge l'application, je lance la méthode play() du Slider et je peux choisir sa vitesse. Plus, le chiffre est grand, plus le curseur sera lent.

timeSlider.set({ loop: false, playRate: 200 }); timeSlider.play();

Le Renderer


Le renderer, c'est la manière dont seront représentées les données sur la carte. Ici j'ai choisi de visualiser le nombre brut de vaccinés par pays et le pourcentage que ça représente rapporté à la population. Pour avoir une lecture intuitive de ma carte, je vais représenter par pays un cercle qui sera de plus en plus gros selon le nombre de vaccinés dans le pays, et la couleur du cercle variera du vert clair au vert foncé selon le pourcentage de vaccinés de la population du pays. On utilisera donc pour cela une visualisation dite multivariée.
Je vais passer dans le tableau visualVariables (propriété du renderer), deux objets JSON pour chaque visualisation. C'est ici qu'on définit si la symbologie de nos entités se fait selon leur taille, leur couleur, l'opacité ou la rotation.

Grâce à la documentation, je peux alors définir pour le premier objet dans le tableau VisualVariable,  le type size, puis je spécifie le nom du champ d'attribut numérique qui contient les valeurs de données utilisées pour déterminer la couleur de chaque entité.

Je peux en option lui donner une étiquette qui sera affiché dans la légende avec legendOptions. La distribution statistique des données de cas étant inégales, je ne vais pas respecter une relation linéaire de taille en fonction du pays contenant le nombre de cas le plus bas et le pays ayant le nombre de cas le plus haut. Je vais donc définir mes propres bornes pour mieux distinguer plusieurs échelles de données. Entre deux bornes, la taille des entités suivra une relation linéaire entre la borne inférieure et supérieure.
 
visualVariables: [{ type: "color", field: "total_vaccinat_1", legendOptions: { title: "Taux de vaccinés contre la Covid-19" }, stops: [{ value: 20, color: [25, 128, 49, 0.8], //"#B03A2E" label: "20 % de vaccinés dans le pays" }, { value: 10, color: [21, 146, 42, 0.8], //"#B03A2E" label: "10 % de vaccinés dans le pays" }, { value: 5, color: [35, 176, 57, 0.8], //"#B03A2E" label: "5 % de vaccinés dans le pays" }, { value: 3, color: [49, 192, 73, 0.8], //"#B03A2E" label: "3 % de vaccinés dans le pays" }, { value: 1, color: [108, 205, 124, 0.8], //"#CB4335" label: "1 % de vaccinés dans le pays" }, { value: 1, color: [141, 222, 154, 0.8], //"#EC7063" label: "0,05 % de vaccinés dans le pays" }] }, { type: "size", field: "total_vaccinatio", legendOptions: { title: "Total des vaccinés Covid-19 dans le pays" }, stops: [{ value: 1000000000, size: "200px" }, { value: 100000000, size: "156px" }, { value: 20000000, size: "128px" }, { value: 5000000, size: "100px" }, { value: 1000000, size: "64px" }, { value: 100000, size: "24px" }, { value: 10000, size: "6px" }, { value: 1000, size: "3px" }, { value: 0, size: "0px" } ] } ]

Avant de conclure, je souhaiterais ajouter que dans le cadre de cette application, une grande composante était la mise à jour des données journalière. Cela se fait par l'exécution d'un script, quotidiennement, tirant parti de l'API ArcGIS Python. Les données ne sont pas homogènes selon les pays, dans le sens où pour certains pays on a des données à certaines dates que d'autres pays n'ont pas. Afin d'avoir un rendu uniforme il a donc fallu uniformiser les données. Donc lorsqu'il manque de la donnée on comble la donnée du jour avec la dernière donnée connue.

Vous pouvez vous abonner à ce blog pour lire d'autres articles sur le développement Web d'applications cartographiques et découvrir comment notre API est une superbe alternative à Google Maps !
Vous voulez vous aussi réaliser des applications Web cartographiques et dynamiques ? N'hésitez pas à souscrire à un plan gratuit ArcGIS for Developers pour développer vos propres applications cartographiques 2D ou 3D ! Cet article résume ce que vous obtiendrez. Et pour en savoir sur l'API c'est ici.

Aucun commentaire:

Enregistrer un commentaire