Rechercher dans le blog

Un mardi, une appli #10 Découvrez comment créer une application représentant le périmètre de confinement de 1 kilomètre

Bonjour, aujourd'hui je vais vous montrer comment développer une application représentant le périmètre de confinement dans lequel nous avons le droit de nous déplacer à pied, grâce à une application développée par mon collègue Pierre-Matthieu Petillot. En effet, depuis quelques jours nous sommes désormais limités à une heure quotidienne de sortie dans un rayon maximal d'un kilomètre autour de chez soi, pour ralentir la propagation du Covid19. Cette sortie peut se faire dans le cadre suivant :
- faire un peu d'activité physique individuelle,
- se promener, uniquement avec les personnes confinées ensemble,
- sortir ses animaux de compagnie.

1. L'application

De plus, Edouard Philippe a annoncé ce vendredi 27 mars 2020 que le confinement serait prolongé jusqu'au 15 avril, ce qui étend la durée de cette consigne à respecter strictement. Il n'est pas forcément évident de savoir précisément jusqu'où l'on peut aller pour respecter cette consigne. C'est pour cette raison que cette application a été développée, pour permettre de localiser votre domicile, puis de calculer ce périmètre restrictif d'un kilomètre à pied par la route, autour de ce lieu de référence. Vous pourrez alors exporter et imprimer cette carte. La carte a d'ailleurs été reprise par LCI sur son site Internet.

Pour utiliser l'application, rien de plus simple : entrez une adresse ou un lieu dans la barre de recherche, ou utilisez votre géolocalisation, puis cliquez sur le bouton Calculer la zone dans la fenêtre contextuelle centrée sur le lieu recherché. Un avantage de cette application est d'afficher sur la carte différents points d'intérêts comme les commerces de proximité qui s'y trouvent, commerces alimentaires, épiceries, supérette, supermarchés, pharmacies, distributeurs automatiques de billets ou encore stations essence et stations service. L'application permet d'aller plus loin que le dessin d'un cercle de un kilomètre, en intégrant les rues et la voirie pour simuler le parcours d'un kilomètre que pourrait réaliser le piéton dans ces rues.

2. Aspect technique

L'application est une page HTML exécutant du JavaScript et utilisant l'ArcGIS API for JavaScript 4.xL'application fait appel à différents widgets pour permettre l'expérience utilisateur la plus optimale. Parmi ceux-ci il y a :

- le widget Search pour chercher n'importe quelle adresse ou lieu en France métropolitaine et dans les DOM. Il consomme un service spécifique de géocodage hébergé sur un ArcGIS Enterprise en France.
Le widget Search peut être utilisé pour rechercher des entités dans un FeatureLayer ou des emplacements de géocodage avec un Locator. La propriété sources permet en effet de définir les sources à partir desquelles nous pouvons faire une recherche d'adresse, dans le but de limiter les résultats et de se concentrer sur une région donnée.

const searchWidget = new Search({ view: view, container: "widget_search", includeDefaultSources: false, popupEnabled: false, // popup is customized so default popup is disabled resultGraphicEnabled: false, // resultGraphic is customized so default resultGraphic is disabled sources: [locatorSearchSource] });

Pour éditer cette source, il faut spécifier et configurer un Locator défini dans notre organisation ArcGIS Online et en le rendant public. C'est dans ce Locator qu'on définit les zones géographiques où nous voulons limiter notre recherche, ici la France métropolitaine et les DOM.

var locator = new Locator({ url: "https://utility.arcgis.com/usrsvcs/servers/60a8871933e44a249ca71bb13c2d823d/rest/services/World/GeocodeServer" });

On peut ensuite définir un LocatorSearchSource pointant vers un Locator qui peut être utilisée pour géocoder des emplacements avec une instance de widget Search. Il permet de configurer le nombre de résultats que nous souhaitons avoir et les suggestions possibles lorsqu'on écrit.

var locatorSearchSource = new LocatorSearchSource({ locator: locator, singleLineFieldName: "SingleLine", name: "Géocodage sur la France", placeholder: "Rechercher une adresse ou un lieu", maxResults: 3, maxSuggestions: 6, suggestionsEnabled: true, minSuggestCharacters: 3 });

- le widget de géolocalisation Locate, grâce à l'adresse IP dont tire parti l'API de géolocalisation de votre navigateur

const locateWidget = new Locate({ view: view, graphic: new Graphic({ symbol: { type: "simple-marker" } // overwrites the default symbol used for the // graphic placed at the location of the user when found }) });

- le widget Scalebar pour afficher une barre d'échelle en vas à gauche de la carte. Le widget respecte divers systèmes de coordonnées et affiche les unités en valeurs métriques ou non métriques. Lorsque vous travaillez en projection Web Mercator ou d'autres systèmes de coordonnées géographiques, la barre d'échelle prend en compte la distorsion de projection et ajuste dynamiquement la barre d'échelle.

// Widget ScaleBar const scaleBarWidget = new ScaleBar({ view: view, style: "line", unit: "metric" });

- le widget Print pour imprimer et exporter votre carte une fois la zone calculée, il faut spécifier le service d'impression haute définition, qui est publié sur un ArcGIS Enterprise, en public. Pour optimiser l'expérience utilisateur, on intègre le widget dans un bouton qui s'ouvrira lorsqu'on cliquera dessus avec le widget Expand.

const printWidget = new Print({ view: view, // specify your own print service printServiceUrl:"https://wssecured.esrifrance.fr/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task" }); // Affichage du widget Print sous forme d'un objet Expand pour ne pas encombrer la vue const printExpand = new Expand({ view: view, content: printWidget, expandTooltip: "Exporter", group: "expands" }); view.ui.add(printExpand, { position: "top-right", index: 1 });

L'API ArcGIS JavaScript 4.x permet de faire applications responsive, c'est à dire avec un affichage adapté en fonction de l'appareil sur lequel on charge l'application. L'API offre des outils pour adapter cet affichage en retirant notamment des widgets pour alléger l'affichage.
La propriété widthBreakpoint de MapView est une chaîne de caractère indiquant la taille générale de la largeur de la vue.
Elle peut prendre les valeurs suivantes : "xsmall"|"small"|"medium"|"large"|"xlarge"
Elle prendra une de ses valeurs en fonction de la largeur en pixels de la vue.
Il est alors facile de configurer un switch dans le code pour établir plusieurs cas selon lesquels on affiche ou non des widgets en fonction de la largeur de l'écran à l'aide d'une fonction.
// RESPONSIVE DESIGN // Init view isResponsiveSize = view.widthBreakpoint === "xsmall"; updateView(isResponsiveSize); // Breakpoints view.watch("widthBreakpoint", function (breakpoint) { switch (breakpoint) { case "xsmall": updateView(true); break; case "small": case "medium": case "large": case "xlarge": updateView(false); break; default: } });

La demande de calcul de la zone d'1 kilomètre se fait dans une popup. Dès qu'on va cliquer sur la carte ou se géolocaliser une popup s'ouvrira avec l'adresse du lieu où nous avons cliqué et cette popup nous proposera alors de Calculer la zone.

On définit une fonction de popup qui va avoir en paramètre le point où l'on a cliqué sur la carte, récupérable via l'événément "click" ou "locate" qui retourne un point. On pourra alors en extraire la latitude et la longitude. 

// Popup affichée lors du clic sur la carte ou en résultat du widget Locate function popupContentClick(point) { var lat = Math.round(point.latitude * 1000) / 1000; var lon = Math.round(point.longitude * 1000) / 1000; var popupContent = "Longitude/Latitude : " + lon + ", " + lat; var locationGraphic = popup(popupContent, point); var params = { location: point }; // Display the popup // Execute a reverse geocode using the clicked location locator.locationToAddress(params).then(function (response) { // If an address is successfully found, show it in the popup's content view.popup.content = setContentInfo(popupContent + "<br>" + response.address, locationGraphic); }) .catch(function (error) { // If the promise fails and no result is found, show a generic message view.popup.content = setContentInfo(popupContent + "<br>Pas d'adresse trouvée pour ce lieu", locationGraphic); }); }

Enfin, on appelle la fonction qu'on vient de définir, soit lorsque le widget de géolocalisation est activé, soit lorsqu'on clique n'importe où sur la carte.

locateWidget.on("locate", function (event) { popupContentClick(event.target.graphic.geometry); });

view.on("click", function (event) { popupContentClick(event.mapPoint); });

Enfin, vient le cœur de l'application, le calcul de la zone d'un kilomètre déclenché après l'appui du bouton dans la popup. La classe ServiceAreaTask vous aide à trouver des zones de service autour de n'importe quel emplacement sur un réseau. Cela correspond à une zone qui englobe toutes les rues accessibles. On appelle cette zone isodistance (ou isochrone, lorsque le calcul est réalisé sur la base d'un temps de parcours du réseau, ce qui n'est pas le cas ici). Par exemple, la zone de service d'1 kilomètre pour un point comprend toutes les rues qui peuvent être atteintes dans un trajet d'1 kilomètre à partir de ce point. Ce service de calcul d'isodistance a été hébergé sur un ArcGIS Enterprise d'Esri France. Il suffit de spécifier son URL dans l'instance définie.

// Calcul de la zone
var serviceAreaTask = new ServiceAreaTask({ url: "https://wssecured.esrifrance.fr/arcgis/rest/services/BDTopo_routing/NetworkAnalysis/NAServer/ServiceArea" });


On définit ensuite les paramètres pour exécuter ServiceAreaTask avec la classe ServiceAreaParameters, où on y définit notamment le référentiel spatial, la limite du calcul d'itinéraire avec la propriété defaultBreaks:

function createServiceAreaParams(locationGraphic, outSpatialReference) { // Create one or more locations (facilities) to solve for var featureSet = new FeatureSet({ features: [locationGraphic] }); // //Set all of the input parameters for the service var taskParameters = new ServiceAreaParameters({ facilities: featureSet, // Location(s) to start from defaultBreaks: [1000], travelDirection: "from-facility", travelMode: "2", // traveMode "Meters" outSpatialReference: outSpatialReference // Spatial reference to match the view }); return taskParameters; }
Une fois que les paramètres sont définis, je peux exécuter la résolution du calcul d'isodistance et dessiner le résultat sur notre carte.
function executeServiceAreaTask(serviceAreaParams) { return serviceAreaTask.solve(serviceAreaParams) .then(function (result) { if (result.serviceAreaPolygons.length) { // Draw each service area polygon result.serviceAreaPolygons.forEach(function (graphic) { graphic.symbol = { type: "simple-fill", color: "rgba(0,122,194,.05)", outline: { // autocasts as new SimpleLineSymbol() color: "rgba(0,122,194,100)", width: 2 } } view.graphics.add(graphic, 0); view.goTo(graphic); }); } }, function (error) { console.log(error); });

Puis, on exécute les fonctions avec d'abord la création des paramètres des services de calcul d'isodistance, avant d'exécuter l'outil en faisant appel au service de calcul d'isodistance hébergé sur un ArcGIS Enterprise.

var serviceAreaParams = createServiceAreaParams(graphicCenter, view.spatialReference); executeServiceAreaTask(serviceAreaParams);


L'application consomme donc le service de géocodage, un service de calcul d'itinéraire et un service d'impression haute-définition, tout les trois publiés par Esri France sur des serveurs ArcGIS Enterprise basés en France. Enfin, la carte contient une couche de points d'intérêt (POI) publiée sur ArcGIS Online et le fond de carte OpenStreetMap en couche vectoriel, dont la symbologie a été personnalisée sur ArcGIS Online. 

N'hésitez pas à consulter le code pour en savoir plus et à me poser des questions.

Vous pouvez vous abonner à ce blog pour lire d'autres articles sur le développement Web d'applications cartographiques et découvrir 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