Fermer

juin 19, 2018

Comment créer une carte Mall avec des données en temps réel en utilisant WRLD –


Cet article a été créé en partenariat avec WRLD . Merci de soutenir les partenaires qui rendent SitePoint possible.

En tant que développeur Web, vous vous trouvez parfois dans une position où vous devez implémenter une carte. Votre premier choix est d'utiliser Google Maps, non?

 google-maps

Cela semble correct. Cependant, vous pouvez être amené à superposer des informations supplémentaires sur la carte à l'aide de marqueurs. Vous pouvez utiliser cette méthode, ou vous pouvez trouver une meilleure solution qui vous permet de créer des marqueurs dans une carte 3D intérieure! À quel point cela est cool? Avec les marqueurs intérieurs, vous pouvez offrir aux utilisateurs des expériences uniques où ils pourront accéder aux informations et interagir avec les interfaces utilisateur directement à l'intérieur de la carte.

 complete-mall-map

Dans ce tutoriel, nous allons créer deux démos illustrant la puissance des cartes WRLD . Vous apprendrez à créer des applications personnalisées qui peuvent superposer des informations en temps réel sur une carte 3D. Dans la première démo, nous ajouterons des marqueurs interactifs à une carte intérieure existante d'un centre commercial. Dans la deuxième démo, nous placerons des polygones colorés sur les aires de stationnement, indiquant la capacité.

Vous pouvez trouver le projet achevé pour les deux démos dans ce dépôt GitHub Prérequis

Pour cela article, vous avez seulement besoin d'avoir une compréhension fondamentale des sujets suivants:

Je suppose que c'est la première fois que vous utilisez des cartes WRLD. Cependant, je vous recommande au moins d'avoir une lecture rapide de l'article:

Vous aurez également besoin d'une version récente de Node.js et de npm installé sur votre système (au moment de l'écriture, 8.10 LTS est la dernière stable version). Pour les utilisateurs Windows, je vous recommande fortement d'utiliser Git Bash ou tout autre terminal capable de gérer les commandes Linux de base.

Ce tutoriel utilisera le fil pour l'installation du paquet. Si vous préférez utiliser npm veuillez vous reporter à ce guide si vous n'êtes pas familier avec les commandes de fils.

Acquérir une clé API

Avant de commencer, vous aurez besoin de créer un compte gratuit sur WRLD . Une fois que vous avez ouvert une session et vérifié votre adresse e-mail, vous devez acquérir une clé API. Pour des instructions détaillées sur la façon d'en acquérir un, veuillez consulter la section Getting Started sur Construire des cartes 3D dynamiques où il est bien documenté.

Approche pour construire la carte

La création de cartes WRLD est une réalisation technologique majeure qui présente de grands avantages potentiels pour de nombreuses industries. Il existe deux façons principales d'étendre les capacités de la plateforme:

  • Utiliser des outils intégrés, par ex. Concepteur de cartes et concepteur de lieux
  • Construction d'une application personnalisée

Permettez-moi de décrire comment chaque méthode peut être utilisée pour obtenir les résultats souhaités.

Utilisation de Map Designer et Places Designer

Pour notre première démo, nous pouvons utiliser Places Designer pour créer des cartes magasin. Cela nous demandera de créer un ensemble de collection où tous les marqueurs de points d'intérêt auront lieu. Cet ensemble peut être consulté à la fois dans l'écosystème WRLD et en externe via la clé API. Nous pouvons transmettre ces données à une carte personnalisée créée à l'aide du concepteur de cartes . Avec cet outil, nous pouvons partager la carte avec d'autres en utilisant son lien généré. Si vous souhaitez en savoir plus sur le processus, veuillez regarder les didacticiels vidéo sur cette playlist YouTube .

 map-tools

La beauté de cette méthode est qu'aucun codage n'est requis . Cependant, dans notre cas, il a des limitations:

  • Conception d'interface utilisateur restrictive – nous ne pouvons utiliser que l'interface utilisateur fournie avec Places Designer
  • Ensemble de données restrictif – nous ne pouvons pas afficher d'informations supplémentaires.

Afin de surmonter ces limitations, nous devons aborder notre défi carte de centre commercial en utilisant la deuxième méthode.

2. Création d'une application personnalisée

La création d'applications personnalisées est l'option la plus flexible. Bien que cela demande un certain effort de codage, cela nous permet de tirer pleinement parti de la richesse du potentiel fourni par la plate-forme WRLD. En créant une application personnalisée, nous pouvons créer notre propre interface utilisateur, ajouter plus de champs et accéder à des bases de données externes en temps réel. C'est la méthode que nous allons utiliser pour ce tutoriel.

Construction de l'application

Créons d'abord une carte de base, à laquelle nous ajouterons plus de fonctionnalités plus tard. Rendez-vous dans votre répertoire d'espace de travail et créez un nouveau dossier pour votre projet. Appelons-le mall-map .

Ouvrez le dossier mall-map dans votre éditeur de code. Si vous avez VSCode, accédez au terminal en utilisant Ctrl + ` et exécutez les commandes suivantes dans le répertoire du projet:

 # Initialiser package.json
npm init -f

# Créer des répertoires de projet
mkdir src
mkdir src / js src / css

# Créer des fichiers de projet
touchez src / index.html
touchez src / js / app.js
touchez src / css / app.css
touchez env.js

Voici à quoi devrait ressembler la structure de votre projet:

 projet-structure

Maintenant que nous avons la structure de notre projet en place, nous pouvons commencer à écrire du code. Nous allons commencer par index.html . Insérer ce code:




  
  
  
  
   Centre commercial 


  
  

Ensuite, travaillons sur css / app.css . Je fournis le style complet pour l'ensemble du projet afin que nous n'ayons pas à revisiter ce fichier à nouveau. Vous comprendrez le contenu au fur et à mesure que vous progresserez avec le tutoriel.

 @import "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.1/leaflet.css";
@import "https://cdn-webgl.wrld3d.com/wrldjs/addons/resources/latest/css/wrld.css";
@import "https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.0/semantic.min.css";

html,
corps {
  marge: 0;
  rembourrage: 0;
  largeur: 100%;
  hauteur: 100%;
}

#map {
  largeur: 100%;
  hauteur: 100%;
  couleur de fond: # 000000;
}

/ * -------- CONTENU POPUP -------- * /
.main-wrapper> .segment {
  rembourrage: 0px;
  largeur: 300px;
}

.contacts> span {
  bloc de visualisation;
  rembourrage-top: 5px;
}

Maintenant, nous devons commencer à écrire du code pour app.js . Cependant, nous avons besoin de deux dépendances de nœuds:

 yarn add wrld.js axios

Comme mentionné précédemment, nous utiliserons la syntaxe JavaScript moderne pour écrire notre code. Par conséquent, nous devons utiliser babel pour compiler notre code moderne dans un format compatible avec la plupart des navigateurs. Cela nécessite d'installer les dépendances babel et de les configurer via un fichier .babelrc . Assurez-vous de les installer comme dev-dépendances .

 yarn Ajoutez babel-core babel-plugin-transformez-runtime babel-runtime --dev
touchez .babelrc

Copiez ce code dans le fichier .babelrc :

 {
  "plugins": [
    [
      "transform-runtime",
      {
        "polyfill": false,
        "regenerator": true
      }
    ]
  ]
}

Nous aurons aussi besoin des paquets suivants pour exécuter notre projet:

Installez globalement les paquets comme ceci:

 yarn global add parcel-bundler json-server

# Commande alternative pour les utilisateurs de npm
npm installer -g parcel-bundler json-server

Voilà toutes les dépendances de nœuds dont nous avons besoin pour notre projet. Écrivons maintenant du code JavaScript. Tout d'abord, fournissez votre clé API WRLD dans env.js :

 module.exports = {
  WRLD_KEY: '',
 }

Puis ouvrez js / app.js et copiez le code suivant:

 const Wrld = require ('wrld.js');
const env = require ('../../ env');

const keys = {
  wrld: env.WRLD_KEY,
}

window.addEventListener ('load', async () => {
  const map = wait Wrld.map ('map', keys.wrld, {
    centre: [56.459733, -2.973371],
    zoom: 17,
    indoorsEnabled: true,
  });
});

Les trois premières déclarations sont assez évidentes. Nous avons mis tout notre code dans la fonction window.addEventListener . C'est pour s'assurer que notre code est exécuté après les dépendances JavaScript, que nous spécifierons plus tard dans index.html ont chargé. A l'intérieur de cette fonction, nous avons initialisé la carte en passant plusieurs paramètres:

  • carte – l'ID du conteneur div spécifié dans index.html
  • keys.wrld – Clé API
  • centre – latitude et longitude du centre commercial Overgate situé à Dundee, Écosse
  • zoom – altitude
  • indoorsEnabled – Permet aux utilisateurs d'accéder à des cartes d'intérieur

Allumons notre projet. Accédez à votre terminal et exécutez:

 parcel src / index.html

Attendez quelques secondes que le projet termine le groupage. Quand c'est fait, ouvrez votre navigateur et accédez à localhost: 1234 . Selon votre vitesse Internet, la carte ne devrait pas prendre trop de temps à charger.

 building-map

Beau, n'est-ce pas? N'hésitez pas à cliquer sur l'icône bleue. Cela vous emmènera à l'intérieur. Naviguez autour de voir les différents magasins. Cependant, vous réaliserez bientôt que vous ne pouvez pas accéder aux autres étages. Il n'y a pas non plus de bouton pour quitter la carte intérieure. Résoutons cela dans le chapitre suivant.

Créer des contrôles internes

Pour permettre aux utilisateurs de basculer entre différents étages, nous leur fournirons un widget de contrôle qui leur permettra de faire cela. Ajoutez simplement les scripts suivants à la section head du fichier public / index.html :

     

Toujours dans le fichier html, ajoutez cette div dans la section body, juste avant la #map div:

  

Mettons maintenant à jour js / app.js pour initialiser le widget. Placez ce code juste après la section d'initialisation de la carte:

 const indoorControl = new WrldIndoorControl ('widget-container', map);

Maintenant, actualisez la page et cliquez sur l'icône "Enter Indoors". Vous devriez avoir un widget de contrôle qui vous permettra de basculer entre les étages. Faites simplement glisser le contrôle vers le haut et vers le bas pour vous déplacer entre les étages.

 indoor-controls

Incroyable, n'est-ce pas? Maintenant, voyons comment nous pouvons rendre notre carte un peu plus pratique pour nos utilisateurs.

Entrer à l'intérieur automatiquement

Ne trouvez-vous pas un peu ennuyeux que chaque fois que nous devons tester notre carte, nous devons cliquer l'icône 'Indoors'? Les utilisateurs peuvent commencer à naviguer vers d'autres endroits, ce qui n'est pas l'intention de cette application. Pour résoudre ce problème, nous devons naviguer à l'intérieur automatiquement lorsque l'application démarre sans aucune intervention de l'utilisateur. Tout d'abord, nous avons besoin de l'identifiant de la carte intérieure pour implémenter cette fonctionnalité. Nous pouvons trouver cette information à partir de l'événement indoormapenter . Vous pouvez trouver toutes les méthodes liées à l'intérieur ici .

Ajouter le code suivant dans le fichier js / app.js .

 ...
// Place ce code juste après l'instruction Wrld.map ()
map.indoors.on ('indoormapenter', async (event) => {
  console.log (event.indoorMap.getIndoorMapId ());
});
...

Actualisez la page puis vérifiez votre console. Vous devriez obtenir cet ID imprimé: EIM-e16a94b1-f64f-41ed-a3c6-8397d9cfe607 . Écrivons maintenant le code qui va effectuer la navigation proprement dite:

 const indoorMapId = 'EIM-e16a94b1-f64f-41ed-a3c6-8397d9cfe607';

map.on ('initialstreamingcomplete', () => {
  map.indoors.enter (indoorMapId);
});

Après avoir enregistré le fichier, actualisez la page et voyez ce qui se passe

La ​​carte du centre commercial intérieur devrait naviguer automatiquement. Ensuite, nous verrons comment nous pouvons créer des cartes pour chaque magasin. Mais d'abord, nous devons déterminer où trouver nos données

Mall Map Planning

Pour créer des cartes magasin pour notre carte, nous avons besoin de plusieurs éléments:

  • Coordonnées exactes Longitude / Latitude d'un magasin
  • informations de contact et heures d'ouverture
  • Modèle de conception pour la carte de magasin

Coordonnées de carte de magasin

Pour acquérir des coordonnées Longitude / Latitude, nous devons accéder à maps.wrld3d.com . Attendez que la carte pour terminer le chargement, puis entrez l'adresse 56.459733, -2.973371 dans la boîte de recherche. Appuyez sur Entrée et la carte se dirigera rapidement vers Overgate Mall. Cliquez sur l'icône bleue intérieure pour Overgate Mall et vous devriez être pris à la carte intérieure du centre commercial. Une fois chargé, localisez le magasin «Suivant» et cliquez avec le bouton droit pour ouvrir le menu contextuel. Cliquez sur "Qu'est-ce que cet endroit? option. La fenêtre de coordonnées devrait apparaître

 coordonnées de lieu

Cliquez sur le bouton «Copier coordonnées». Cela vous donnera les coordonnées exactes de longitude / latitude du magasin. Enregistrer cette adresse de lieu temporairement

Informations sur la carte de magasin

Vous devrez également collecter des informations de contact de chaque magasin qui comprend:

  • image
  • description
  • téléphone
  • email
  • web
  • Twitter
  • heures d'ouverture

Vous pouvez obtenir la plupart de ces informations auprès de Google. Heureusement, j'ai déjà collecté les données pour vous. Pour ce tutoriel, nous ne traiterons qu'avec quatre magasins au rez-de-chaussée. Pour accéder aux informations, créez simplement un dossier à la racine du projet et appelez-le data. Ensuite, enregistrez ce fichier de GitHub dans le dossier data . Assurez-vous de l'enregistrer en tant que db.json . Voici un échantillon des données que nous utiliserons:

 {
  "id": 1,
  "titre": "JD Sports",
  "lat": 56.4593425,
  "long": -2.9741433,
  "floor_id": 0,
  "image_url": "https://cdn-03.belfasttelegraph.co.uk/business/news/...image.jpg",
  "description": "Chaîne de vente au détail spécialisée dans les chaussures d'entraînement, les vêtements de sport et les accessoires.",
  "téléphone": "+44 138 221 4545",
  "email": "customercare@jdsports.co.uk",
  "web": "https://www.jdsports.co.uk/",
  "twitter": "@jdhelpteam",
  "tags": "shopping sportif",
  "open_time": [
    { "day": "Mon",
      "time": "9:30am - 6:00pm"
    },]
}

Les données sont stockées dans un tableau étiqueté 'pois'. POI signifie Lieux d'intérêt. Maintenant que nous avons les données disponibles, nous pouvons facilement les rendre accessibles via un point REST API en exécutant le serveur JSON . Ouvrez simplement un nouveau terminal et exécutez la commande:

 json-server --watch data / db.json

L'API doit prendre quelques secondes pour démarrer. Une fois qu'il est complètement chargé, vous pouvez le tester avec votre navigateur à localhost: 3000 / pois . Vous pouvez également extraire un seul POI en utilisant cette syntaxe:

- localhost: 3000 / pois / {id}

Par exemple, localhost: 3000 / pois / 3 devrait retourne un enregistrement poi avec l'ID 3 au format JSON

Store Card Design

Nous utiliserons un thème propre et élégant pour afficher les informations de contact et les heures d'ouverture en utilisant quelques onglets. Nous allons créer des marqueurs qui afficheront une fenêtre contextuelle lorsque vous cliquerez dessus. Cette fenêtre aura l'interface utilisateur suivante:

 store-card-template

Le code pour ce design HTML est un peu long à mettre ici. Vous pouvez voir et télécharger le fichier à partir de ce lien . La conception n'a que trois dépendances:

  • CSS sémantique CSS
  • jQuery
  • UI sémantique JS

Maintenant que nous avons les données requises et la conception, nous devrions être prêts à commencer à travailler sur notre carte intérieure. 19659114] Implémentation de cartes magasin dans la carte intérieure

Commençons par créer un service qui nous permettra d'accéder aux données des API REST JSON. Ces données seront utilisées pour remplir les cartes de magasin avec les informations nécessaires. Créez le fichier js / api-service.js et copiez le code suivant:

 const axios = require ('axios');

const client = axios.create ({
  baseURL: 'http://127.0.0.1:3000',
  délai d'expiration: 1000,
});

module.exports = {
  getPOIs: async () => {
    essayez {
      const response = attendez client.get ('/ pois');
      retourner response.data;
    } catch (erreur) {
      console.error (erreur);
    }
    retour [];
  },
  getPOI: async (id) => {
    essayez {
      const response = attendez client.get (`/ pois / $ {id}`);
      retourner response.data;
    } catch (erreur) {
      console.error (erreur);
    }
    revenir {};
  },
}

Nous utilisons ici la bibliothèque axios pour demander des données au serveur JSON

Ensuite, nous allons convertir notre design HTML statique pour la carte Store en un format qui nous permettra rendre des données. Nous allons utiliser JsRender pour cela. Nous décomposerons notre conception statique en trois modèles:

  • Base Template - contient des conteneurs pour les onglets de menu, d'information et de temps
  • Info Template - onglet pour les informations de contact de magasin
  • Time Template - onglet pour ouverture de magasin

Tout d'abord, ouvrez index.html et ajoutez ces scripts à la section head juste après les scripts de contrôle jQuery et indoor:


   ...
    ...

Ensuite, copiez cette section du code juste avant le widget-container div:

   ...
   
...

Voici à quoi devrait ressembler le code complet pour index.html

Ensuite, créons un autre service qui gérera la création de Popups . Créez le fichier js / popup-service.js et copiez le code suivant:

 const Wrld = require ('wrld.js');
const {getPOI} = require ('./ api-service');

const baseTemplate = $ .templates ('# baseTemplate');
const infoTemplate = $ .templates ('# infoTemplate');
const timeTemplate = $ .templates ('# timeTemplate');

const popupOptions = {
  indoorMapId: 'EIM-e16a94b1-f64f-41ed-a3c6-8397d9cfe607',
  indoorMapFloorIndex: 0,
  autoClose: true,
  closeOnClick: vrai,
  élévation: 5,
}

Permettez-moi d'expliquer chaque bloc pas à pas:

  • Bloc 1: WRLD est requis pour créer le Popup La fonction getPOI est requise pour récupérer des données
  • Bloc 2 : Les modèles que nous avons discutés précédemment sont chargés en utilisant jsrender
  • Bloc 3: Les paramètres qui seront passés pendant Popup instanciation. Voici la documentation de référence .

Ensuite, ajoutons les onglets qui seront utilisés pour changer d'onglet. Ajoutez simplement ce code à js / popup-service.js :

 const createMenuLink = (linkName, iconClass) => {
  lien const = document.createElement ('a');
  link.className = 'item';
  icône const = document.createElement ('i');
  icon.className = `$ {iconClass} icône`;
  link.appendChild (icône);
  link.appendChild (document.createTextNode (`$ {linkName}`));
  link.setAttribute ('data-tab', linkName);
  link.addEventListener ('click', () => {
    $ .tab ('change tab', linkName);
    $ ('. item'). toggleClass ('actif');
  });
  lien de retour;
}

const createMenu = (menuParent) => {
  const infoLink = createMenuLink ('Info', 'cercle d'informations');
  infoLink.className + = 'actif';
  menuParent.appendChild (infoLink);
  const timeLink = createMenuLink ('Heure', 'horloge');
  menuParent.appendChild (timeLink);
}

Vous vous demandez peut-être pourquoi nous utilisons une méthode complexe de création de liens de menu. Idéalement, nous devrions pouvoir les créer en HTML, puis ajouter un petit script JavaScript pour activer les onglets. Malheureusement, cela ne fonctionne pas dans le contexte d'un Popup . Au lieu de cela, nous devons créer des éléments cliquables en utilisant des méthodes de manipulation DOM.

Ensuite, ajoutez ce code pour compléter la section de contenu de base:

 const buildBaseContent = () => {
  const htmlOutput = baseTemplate.render ({});
  const parent = $ .parseHTML (htmlOutput) [1];
  const menuParent = parent.childNodes [1] .childNodes [1];
  createMenu (menuParent);
  retour parent;
}

const baseContent = buildBaseContent ();

Ici, nous rendons le modèle de base en HTML. Ensuite, nous le convertissons en DOM pour nous permettre d'attacher notre menu DOM. Nous appelons ensuite la fonction buildBaseContent () pour créer notre DOM de base auquel nous attachons plus tard du contenu pour les onglets d'information et de temps.

Dans la section suivante, nous allons créer une fonction appelée montrerPopup . Nous créerons plus tard des marqueurs pour chaque magasin. Lorsqu'un utilisateur clique sur un marqueur, une fenêtre contextuelle contenant la carte de magasin s'affiche. Ajoutez ce code à js / popup-service.js :

 // Effacer le contenu de l'onglet existant avant d'en ajouter un autre
const clearTab = (onglet) => {
  while (tab.firstChild) {
    tab.removeChild (tab.firstChild);
  }
}

module.exports = {
  showPopup: async (événement) => {
    // Récupère les coordonnées et mappe les objets de l'événement
    const latlang = event.target._latlng;
    const map = événement.target._map;
    // Crée une instance de Popup
    const popup = Wrld.popup (popupOptions)
      .setLatLng (latlang);
    essayez {
      // Récupère les données d'api-service
      const poi = wait getPOI (event.target.options.id);
      // Lier des données avec des modèles pour rendre les sorties html
      const infoHTML = infoTemplate.render (poi);
      const timeHTML = timeTemplate.render (poi);
      // Convertir les sorties HTML en objets DOM
      const infoDOM = $ .parseHTML (infoHTML) [1];
      const timeDOM = $ .parseHTML (timeHTML) [1];
      // Remplir les onglets avec des objets DOM
      const infoTab = baseContent.childNodes [1] .childNodes [3];
      clearTab (infoTab); // Effacer le contenu existant, le cas échéant
      infoTab.appendChild (infoDOM);
      const timeTab = baseContent.childNodes [1] .childNodes [5];
      clearTab (timeTab); // Effacer le contenu existant, le cas échéant
      timeTab.appendChild (timeDOM);

      // Populate popup avec le contenu DOM
      popup.setContent (baseContent);
      // Afficher le popup
      popup.addTo (carte);
      // Naviguer sur la carte pour voir correctement le popup
      map.setView (latlang, 18);
    } catch (erreur) {
      popup.setContent ('Oups, quelque chose s'est mal passé');
      popup.addTo (carte);
    }
  },
}

Il se passe beaucoup de choses ici. J'ai souligné le code avec des commentaires expliquant ce que chaque section fait. Si vous avez des doutes sur l'apparence du code complété, vous pouvez le voir à partir de ce lien .

Ensuite, nous devons créer des marqueurs pour chaque POI défini dans db.json . Chaque marqueur aura un écouteur d'événement cliquez sur ce qui déclenchera la fonction showPopup () . Mise à jour js / app.js comme suit:

 ..
const {getPOIs} = require ('./ api-service');
const {showPopup} = require ('./ popup-service');
...

// Place dans window.addEventListener ('load')
const placeMarkers = (pois) => {
  laisser le marqueur;
  pois.forEach ((poi) => {
    const latlang = [poi.lat, poi.long];
    marqueur = Wrld.marker (latlang, {
      id: poi.id,
      titre: poi.title,
      indoorMapId,
      indoorMapFloorId: 1,
    }). addTo (carte);
    marker.on ('click', showPopup);
  });
}

map.indoors.on ('indoormapenter', async (event) => {
  if (event.indoorMap.getIndoorMapId () === indoorMapId) {
    // Centrer la carte correctement à l'intérieur
    map.indoors.setFloor (0);
    map.setView ([56.459342, -2.9741433]18);

    // Crée des marqueurs pour chaque magasin.
    const pois = attente getPOIs ();
    Marqueurs de lieu (pois);
  }
});

Prenez note que nous transmettons l'ID de POI au marqueur via le paramètre d'objet Options. Si vous vous référez à la fonction showPopup vous verrez que nous extrayons cet identifiant via l'objet . En cas de doute sur l'apparence du code complet, affichez-le à partir de ce lien .

Il est maintenant temps de tester notre code. Je suppose que vous avez toujours le serveur JSON en arrière-plan. Si ce n'est pas le cas, veuillez vous reporter à la façon de l'exécuter. Commençons aussi le bundler de colis. Une fois que cela a commencé, actualisez votre navigateur au cas où ce ne serait pas le cas. Vous devriez maintenant avoir plusieurs marqueurs disponibles pour vous de cliquer. Cliquer sur un marqueur donnera un popup comme ceci:

 store-card-finished

La démo ci-dessus illustre le fonctionnement des cartes Store pour une carte intérieure. Maintenant, regardons une autre fonctionnalité de Wrld.js où nous pouvons superposer des informations de disponibilité de parking sur plusieurs parkings.

Disponibilité de stationnement

Avez-vous déjà été stressé à la recherche d'une place de stationnement? Eh bien, essayons de voir si nous pouvons résoudre ce problème. Nous allons utiliser les cartes WRLD pour mettre en évidence les zones de stationnement. Nous utiliserons différentes couleurs pour indiquer l'état de chaque aire de stationnement:

  • vert: espace de stationnement disponible
  • jaune: 80% de l'espace de stationnement occupé
  • rouge: 100% de l'espace de stationnement occupé

vous pouvez définir plus de codes de couleur pour fournir des niveaux de stationnement plus détaillés. Cependant, n'oubliez pas que les personnes peuvent être pressées et qu'elles doivent traiter cette information en quelques millisecondes. Commençons à créer cette carte une étape à la fois.

1. Positionnement de la carte pour les zones de stationnement

Commençons par créer parking.html et js / parking.js . Nous exécuterons cette solution indépendamment de la logique de la carte du centre commercial. Une fois que vous avez créé le fichier HTML, copiez le code suivant:




  
  
  
  
   Disponibilité du stationnement 


  
  

Ensuite, copiez ce code pour js / parking.js :

 const Wrld = require ('wrld.js');
const env = require ('../../ env');

const keys = {
  wrld: env.WRLD_KEY,
}

window.addEventListener ('load', async () => {
  // Créer une instance de carte
  const map = wait Wrld.map ('map', keys.wrld, {
    centre: [56.460087, -2.975432],
    zoom: 17,5,
  });
});

Maintenant, exécutons notre code. Nous allons utiliser parcelle pour cela. Arrêtez les instances de parcelle existantes en commençant par Ctrl + C. Pour démarrer la démo du parking, exécutez:

 parcel src / parking.html

Attendez la fin de la compilation de la parcelle. Une fois cela fait, naviguez jusqu'à localhost: 1234 . Vous devriez avoir la vue suivante sur les aires de stationnement:

 parking-area-start

2. Mettre en évidence le stationnement

Apprenons maintenant comment mettre en évidence une zone en utilisant une instance de Polygon . Tout d'abord, nous devrons collecter des coordonnées pour chaque coin de la zone que nous devons mettre en évidence. Nous pouvons le faire en visitant maps.wrld3d.com et en recherchant Overgate afin de localiser les aires de stationnement. Zoomez vers la zone de stationnement et utilisez le bouton central de la souris pour régler l'inclinaison de la caméra de sorte que vous puissiez la voir vers le bas. Cela rendra facile de placer avec précision des clics de souris. Ensuite, choisissez l'une des zones de stationnement et faites un clic droit sur un coin. Cliquez sur "Quel est cet endroit?":

 parking-coordinate

Cliquez sur les coordonnées de copie et enregistrez-le quelque part. Vous devriez obtenir les coordonnées Longitude et Latitude du point sur lequel vous avez cliqué.

- 56.460080, -2.974528

Faites ceci pour chaque coin. Ensuite, utilisez ces données pour construire une instance Polygon . Voici un exemple qui a été ajouté à js / parking.js . Placez ce code juste après l'instruction d'initialisation map .

   const polygonPoints1 = [
    [56.459857, -2.974004],
    [56.459889, -2.974036],
    [56.459836, -2.974188],
    [56.460079, -2.974526],
    [56.460254, -2.974096],
    [56.459954, -2.973698]];
  const parking1 = Wrld.polygon (pointsPolygon1) .addTo (carte);

Actualiser localhost: 1234 au cas où ce ne serait pas le cas. Vous devriez maintenant avoir cette vue:

 parking-area-highlight

Maintenant que nous avons appris à faire la mise en évidence, nous devrions collecter des coordonnées pour chaque zone de stationnement qui nous intéresse. Nous avons également besoin d'un moyen de garder ces données loin de notre code que nous allons examiner ensuite. Mais d'abord, supprimez cette section de code car nous la remplacerons par quelque chose de mieux.

API de repos pour les données de stationnement

Nous utiliserons la base de données du serveur JSON pour stocker toutes les coordonnées de stationnement. Heureusement pour vous, j'ai déjà recueilli ces données et les ai placées dans db.json . Voici un exemple de données pour une zone de stationnement:

 {
      "id": 1,
      "nom": "parking 1",
      "polygonPoints": [
        [
          56.459837,
          -2.973982
        ],
        [
          56.459952,
          -2.973691
        ],
        [
          56.460256,
          -2.974093
        ],
        [
          56.460079,
          -2.974530
        ],
        [
          56.459832,
          -2.974188
        ],
        [
          56.459888,
          -2.974035
        ]
      ],
      "totalSlots": 55,
      "usedSlots": 55
    },

Prenez note qu'il y a une estimation approximative du nombre total de places de stationnement disponibles. J'ai également fait une estimation sur les places de stationnement utilisées, avec lesquelles nous pourrons jouer plus tard. Le fichier db.json que vous avez copié précédemment contient déjà ces données. Maintenant que nous avons les données disponibles pour les aires de stationnement, nous devrions créer un service d'assistance pour aller chercher cette information. Nous avons simplement besoin de mettre à jour js / api-service avec une nouvelle fonction. Copiez ce code et placez-le juste après la dernière get fonction dans module.exports :

  getParkingAreas: async () => {
    essayez {
      const url = id? `/ parkingAreas / $ {id}`: '/ parkingAreas';
      const response = attendez client.get (url);
      retourner response.data;
    } catch (erreur) {
       console.error (erreur);
    }
    retour [];
  },

Cette fonction est conçue pour gérer à la fois l'extraction de tous les enregistrements de zones de stationnement ou d'un seul enregistrement, selon que le champ ID est rempli ou non. Voyons maintenant comment nous pouvons extraire ces données du serveur JSON et les superposer sur la carte.

3. Codage par couleur des zones de stationnement

Mise à jour js / parking.js avec ces codes couleurs. Placez ce code après la déclaration des touches .

 // Codes couleurs
const fullColor = [255, 0, 0, 128]; // Complètement complet, 100%
const presqueColor = [255, 165, 0, 128]; // Peu de places de stationnement restantes, 80% pleines
const availableColor = [0, 255, 0, 128]; // Beaucoup d'espace de stationnement disponible

const getColorCode = (parkingArea) => {
  const occupé = (parkingArea.usedSlots / parkingArea.totalSlots) * 100;
  si (occupé === 100) {
    return fullColor;
  } else if (occupé> = 80) {
    retourne presqueCouleur;
  }
  return availableCouleur;
}

Les codes de couleur sont simplement des tableaux représentant des valeurs pour rgba, c'est-à-dire rouge, vert, bleu et alpha. Il y a aussi la fonction getColorCode qui détermine le code de couleur à utiliser en fonction du pourcentage d'emplacements utilisés. Ensuite, extrayons les données de zones de stationnement du serveur JSON et créons une instance Polygon pour chaque enregistrement:

   // Placez-le en haut après les autres importations
  const {getParkingAreas} = require ('./ api-service');
  const parkPolys = [];
  ....
  // Place après la fonction `map`
  map.on ('initialstreamingcomplete', async () => {
    // Mettre en évidence les aires de stationnement
    const parkingAreas = wait getParkingAreas ();
    parkingAreas.forEach ((parkingArea) => {
      const colorCode = getColorCode (parkingArea);
      const poly = Wrld.polygon (parkingArea.polygonPoints, {couleur: colorCode})
        .addTo (carte);
      parkPolys.push ({id: parkingArea.id, poly});
    });
  });
  ...

Prenez note que nous sauvegardons une association de polygone et parkingArea.id dans un tableau. Nous y travaillerons plus tard pour rendre notre carte en temps réel. Assurez-vous que le serveur JSON est en cours d'exécution pour que ce code fonctionne. For now, refresh the page to see the updated results:

parking-color-codes

Pretty cool, isn’t it? Feel free to add color code labels to indicate their meaning. Now, the current limitation with the map is that users can’t see the map update unless they refresh the whole page. Let’s see how we can fix that.

4. Real-time Parking Zones

For this we’ll use the sockets.io library to implement real-time updates. The json server program we are using doesn’t support sockets.io natively. Hence we need to write our own custom implementation. First, let’s install the necessary dependencies:

yarn add json-server socket.io socket.io-client

Next, create the file server.js at the root of the project and copy this code:

const jsonServer = require('json-server');
// Initialize Socket.IO Server
const socketServer = require('http').createServer();
const io = require('socket.io')(socketServer);

// Initialize JSON Server
const server = jsonServer.create();
const router = jsonServer.router('./data/db.json');

// Set default middlewares (logger, static, cors and no-cache)
const middlewares = jsonServer.defaults();
server.use(middlewares);

// To handle POST, PUT and PATCH you need to use a body-parser
// You can use the one used by JSON Server
server.use(jsonServer.bodyParser);

// Broadcast `parkingAreas` PATCH requests
server.patch('/parkingAreas/:id', (req, res, next) => {
  const { id } = req.params;
  const { usedSlots } = req.body;
  console.log(`Parking Area ${id} updated to ${usedSlots} Used Slots`);
  io.emit('parkingAreas', { id, usedSlots });
  next(); // pass on to default logic
});

// Use default router
server.use(router);

// Bind JSON Server
server.listen(3000, () => {
  console.log('JSON Server is running at port 3000');
});

// Bind Socket.IO Server
socketServer.listen(3001, () => {
  console.log('Socket.IO Server is running at port 3001');
});

In the above code, we are setting up two server instances that will run concurrently. The first instance, json server will provide the API services on port 3000. The second instance, socket serverwill provide real-time to socket clients that will connect to it at port 3001.

For this article, we’ll use Postman to send out updates on the capacity levels (usedSlots) for each parking lot. The HTTP method we’ll use is PATCH, which will allow us to update only a subset of a record. We can’t use the UPDATE method as that will overwrite the entire record, causing us to lose the polygon points data.

Back to our server code, you’ll notice that we have a patch function. Within this function, the id and usedSlots data is extracted and then broadcasted to any listening socket.io client.

Now that we’ve setup our server, it’s time to setup our client code to receive real-time updates. Go back to js/parking.js and copy the following code:

// Place this at the top section
const io = require('socket.io-client');
...
  // Place after `getColorCode` function
const updateParkingArea = async ({ id }) => {
  const parkingArea = await getParkingAreas(id);
  if (parkingArea) {
    const parkPoly = parkPolys.find(target => parkingArea.id === target.id);
    if (parkPoly) {
      parkPoly.poly.setColor(getColorCode(parkingArea));
    }
  }
};

const socket = io.connect('http://localhost:3001');

socket.on('connect', () => {
  console.log('connected to socket 3001');
  socket.on('parkingAreas', (data) => {
    console.log('parkingAreas event received');
    updateParkingArea(data);
  });
});

The client code here is pretty simple. We create a socket client instance that is bound to port 3001. We then set it up to listen for parkingAreas events, at which point the updateParkingArea() function is executed.

Please refer to the completed parking.js if in doubt about how the code is arranged.

Now let’s perform an experiment. First you need to cancel any existing processes. Next, start the custom JSON server code on a separate terminal. Then start the parking.html code on a separate terminal:

# Start server first
node server

# Start Parking Map App
parcel src/parking.html

Now open or refresh the page localhost:1234. To send updates to the JSON server, we’ll use Postman. Simply install it if you don’t have it. Once its open, create a new Request and enter the following parameters:

  • Method – PATCH
  • URL – localhost:3000/parkingAreas/2
  • Content-Type – application/json
  • Encoding – raw, JSON(application/json)
  • Body{ "usedSlots": 75 }

In case you don’t know where the field Content-Type is, just click the Header tab. Here is a screenshot of Postman:

postman-patch

When you hit send, the update on the map happens instantly:

real-time-update

Feel free to play around with the value of usedSlots for other records and see the map update itself. Quite brilliant!

Summary

Now that we have come to the end of the tutorial, I hope that you’ve been amazed by the possibilities of what you can do with WRLD’s 3D maps. These demos that can be integrated with real world data, and the applications for WRLD in the real world, are endless.

For example, we can build a service that fetches data from actual parking sensors. For the mall map, we can display more interesting information, such as daily offers which can entice more people to visit the mall. This kind of technology doesn’t just apply to malls, but can be applied to other types of businesses and institutions. For example, you can integrate this map technology with an inventory management system. The map can be used to visualize where equipment is located on the business premises.

It’s truly up to you to come up with innovative products using the WRLD mapping platform.




Source link