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?
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.
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 .
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:
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:
- Packard de parcelles – c'est comme une version simplifiée de webpack avec une configuration presque nulle
- JSON Server – pour créer un serveur d'API fictif
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.
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.
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
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:
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:
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:
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?":
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:
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:
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 server
will 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:
When you hit send, the update on the map happens instantly:
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