Fermer

mai 4, 2018

Comment construire une carte de bureau intérieur avec WRLD –


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

Nous sommes sur le point d'encapsuler notre série sur la plateforme WRLD. Jusqu'à présent, nous avons examiné comment utiliser WRLD avec des cartes externes. Dans ce tutoriel, nous allons concevoir et utiliser une carte intérieure (également connue sous le nom de plan d'étage, si vous voulez être pédant à ce sujet comme un Dwight Schrute). Comme vous pourriez le dire, je pense que The Office serait un bon thème pour celui-ci. Commençons par une citation:

Aurais-je jamais quitté cette société? Regardez, je suis tout à propos de la loyauté. En fait, j'ai l'impression qu'une partie de ce pour quoi je suis payé est ma loyauté. Mais s'il y avait un autre endroit qui valorisait davantage la loyauté … Je vais là où ils attachent le plus de valeur à la loyauté. – Dwight K. Schrute

Dans ce tutoriel, nous allons aborder les sujets suivants:

  • Création d'une carte intérieure
  • Importation de la carte dans WRLD
  • Mise en évidence de pièces spécifiques
  • Création un programme et une boucle à travers lui

Le code de ce tutoriel a été testé avec une version moderne de Chrome.

Création de cartes d'intérieur

Nous allons essayer de recréer le bureau d'après The Office . Je pense que ça va être un défi un peu amusant. Nous allons commencer par installer un logiciel. Je suis sur un Mac, donc ce sont les instructions pour le faire sur un Mac. Apparemment, c'est beaucoup plus simple sur Windows …

Le premier logiciel dont nous avons besoin s'appelle QGIS. Vous pouvez le télécharger directement à partir de sur leur site mais le lien Mac va hors site vers un endroit plutôt douteux. Je suis un peu plus confiant avec le logiciel que je peux installer via Homebrew parce que je peux voir ce qu'il fait à chaque étape du chemin. Si vous êtes sur un Mac, et que vous n'avez pas encore Homebrew, je vous suggère de l'installer. Une fois cela fait, vous pouvez démarrer l'installation de QGIS via certains paquets Python:

 brew install gdal
infuser installer python

Lorsque j'ai essayé d'installer python Homebrew m'a dit que j'avais déjà installé Python. Cependant, la commande pip était manquante. J'ai dû réinstaller python en utilisant infuser réinstaller python ; et puis j'ai dû le relier en utilisant brasser unlink python && brew link python . Après cela, j'ai eu la commande pip .

Vous pouvez suivre ceci avec:

 pip install matplotlib
pip installer psycopg2
robinet d'infusion osgeo / osgeo4mac
infuser installer qgis2

Tout cela fonctionne, au moment de l'écriture. Ce n'est pas une garantie que cela fonctionnera au moment où vous lirez ceci. Vous devrez peut-être recourir au site de téléchargement QGIS apparemment officiel, mais tout à fait douteux que j'ai mentionné plus tôt.

J'ai appris ce processus à partir d'un tutoriel, à propos de qui installe QGIS via Homebrew .

Après tout cela, vous devriez être capable d'exécuter la commande qgis2

 "Mises à jour? Je viens d'installer cette chose! "

Vous aurez également besoin d'installer quelques plugins. Allez à Plugins → Gérer et installer les plugins. Installez le plugin OpenLayers et le plugin Lat Lon Tools

 Tous les plugins

Ensuite, nous devons déterminer où c'est. Dans le spectacle, il est dit que le bureau est situé au 1725 Slough Avenue à Scranton, PA. L'emplacement actuel du bâtiment est vraiment à 13927 rue Saticoy à Panorama City, CA.

La façon la plus simple de confirmer un emplacement de carte (si vous vous souvenez de l'apparence de l'endroit) est de rechercher l'adresse dans quelque chose comme Google Maps, qui fournit un mode d'affichage de la rue. Juste pour prouver que l'emplacement de Panorama City est le bon, j'ai cherché cette adresse dans la vue de la rue, et j'ai obtenu ceci:

 On dirait le bureau.

Maintenant, il est temps de commencer à créer la carte. Ajoutez une nouvelle couche OpenStreetMap en allant sur Web → OpenLayers plugin → OpenStreetMap → OpenStreetMap. Vous devriez voir une carte agrandie du monde. Aller à Plugins → Lat Lon Outils → Zoomer sur Latitude, Longitude et entrer les coordonnées que vous voulez (dans ce cas: 34.2107329, -118.4365886). Vous pouvez changer l'échelle à 1: 500 pour regarder de plus près

 Regarde vers la droite

Ensuite, cliquez sur Raster → Georeferencer → Georeferencer. Cela fera apparaître une nouvelle fenêtre vide. Cliquez sur Fichier → Ouvrir un raster pour sélectionner le plan d'étage. "Quel plan d'étage?", Demandez-vous. Le même que vous pouvez télécharger en cherchant "Plan d'étage de l'Office".

Je devrais mentionner que l'on vous demandera quel type de système de coordonnées de référence (CRS ou SRS) vous avez besoin. Sélectionnez "WGS 84 / Pseudo Mercator". Je ne comprends pas vraiment pourquoi, mais c'était le défaut et ça a bien marché pour moi! Le plan d'étage devrait alors être affiché dans l'éditeur

 Travailler avec le plan

Nous devons lier la carte intérieure à la carte extérieure. Cliquez sur Ajouter un point (dans la fenêtre Georeferencer) et cliquez sur un point de périmètre (comme le coin du bâtiment). Puis cliquez sur De la carte et sélectionnez le point correspondant sur la carte extérieure.

Répétez l'opération plusieurs fois. Je sais qu'il est probablement techniquement incorrect de faire correspondre la carte intérieure 1: 1 avec la forme du bâtiment extérieur, mais c'est ce que j'ai fait pour l'instant. N'hésitez pas à faire de même. Essayez d'être aussi précis que possible.

Lorsque vous êtes satisfait des points que vous avez mappés, cliquez sur Paramètres → Paramètres de transformation et faites en sorte que les paramètres ressemblent à ceci:

 Les paramètres de transformation

La plupart de ces paramètres sont définis par défaut, mais le SRS cible doit être EPSG: 3857. Cliquer sur. Puis cliquez sur le bouton de lecture vert (qui est le bouton Démarrer le géoréférencement). Cela vous ramènera à la fenêtre principale de QGIS, sauf que maintenant le plan d'étage recouvrira la carte extérieure. Vous pouvez cliquer avec le bouton droit sur le plan d'étage, dans le panneau des couches, puis cliquer sur Propriétés. Là, vous pouvez ajuster le mode de fusion à quelque chose d'un peu moins choquant. J'aime le mode de dégradé Allure.

 Modes de fusion

Maintenant, nous devons commencer à dessiner des traits sur le plan d'étage. Cliquez sur Calque → Créer un calque → Nouveau calque de Shapefile. Définissez Type to Polygon, choisissez le même SRS d'EPSG: 3857 et ajoutez les attributs type name et highlight à la liste des attributs. Les valeurs par défaut de "Text data" et "80" conviennent aux attributs de type et de nom, mais l'attribut highlight doit être défini sur integer. Les valeurs du champ Longueur n'ont pas besoin d'être modifiées. Cliquez sur OK et donnez un nom au fichier de forme.

Lorsque vous le voyez dans le panneau des calques, double-cliquez dessus et réglez la transparence sur 50% pour que vous puissiez toujours voir la carte en dessous. Le calque de formes doit être le calque supérieur, alors faites le glisser s'il n'est pas déjà là. Ensuite, cliquez sur le bouton Toggle Editing (le crayon), puis sur le bouton Add Features (qui ressemble à un blog vert avec une icône jaune au-dessus)

Tracez la limite du plan d'étage. Lorsque vous avez fait cela, faites un clic droit sur la forme que vous avez créée et donnez-lui un type de building_outline . Ceci est la limite de la façon dont WRLD rendra la carte intérieure. Cliquez à nouveau sur le bouton Ajouter des entités et commencez à tracer des éléments tels que les murs, les fenêtres, les portes et les pièces. Ceux-ci ne devraient pas se chevaucher. Lorsque vous avez tracé un segment, donnez-lui le type correspondant, comme mur fenêtre porte ou pièce . Vous pouvez généralement laisser le champ "nom" vide, mais si vous spécifiez un nom de pièce, WRLD l'affichera. Si vous envisagez d'utiliser des surbrillances, vous pouvez ajouter un 1 aux attributs de la pièce dans l'attribut surligner .

 Caractéristiques du dessin ]

C'est un peu moins chaotique si vous dessinez des pièces à la place des murs, des fenêtres et des portes qui les composent. Il y a une liste complète des éléments que vous pouvez tracer (et leurs types) ici . Gardez les fonctions de traçage jusqu'à ce que vous ayez autant de détails que nécessaire.

Avant de pouvoir importer la carte dans WRLD, nous devons nous assurer que les ID des entités sont uniques. Si vous avez donné des ID uniques, alors vous êtes tous ensemble. Sinon, ouvrez la liste des fonctionnalités en cliquant sur Calque → Ouvrir le tableau d'attributs et attribuez un ID à chaque entité. L'ordre n'a pas d'importance.

Cliquez avec le bouton droit sur le calque du fichier de formes et cliquez sur Enregistrer sous. Pour télécharger votre bâtiment, vous devez maintenant mettre à jour le fichier CRS vers EPSG: 4326 et l'exporter sous la forme d'un fichier geojson plutôt que d'un fichier de formes. La conversion en 4326 change le format de Pseudo-Mercator en Mercator, ce qui signifie que les points de votre plan de construction sont stockés en latitude et longitude – que WRLD Indoor Map Designer utilise pour placer votre carte correctement dans le monde lors de la conversion en 3D modèle. Enregistrez le fichier quelque part, et ouvrez votre éditeur de texte dans le même dossier dans lequel vous avez enregistré le fichier de calque de forme. Créez un nouveau fichier JSON, appelé main.json :

 {
    "id": "le-bureau",
    "nom": "Le Bureau",
    "propriétaire": "Dunder Mifflin",
    "emplacement": {
        "type": "Point",
        "coordonnées": [-118.4365886, 34.2107329]
    },
    "niveaux": [
        {
            "id": "the-office-1",
            "name": "1",
            "readable_name": "First floor",
            "z_order": 0,
            "filename": "floor-plan.geojson"
        }
    ]
}

Ceci vient de main.js

Le champ id est juste quelque chose pour que vous reconnaissiez la carte par. Vous pouvez mettre quelque chose là-bas. Nom est le nom lisible par l'homme de la carte. Le propriétaire est le nom de votre entreprise (ou de l'entreprise revendiquant le bâtiment sur WRLD). L'emplacement est le point sur la carte où vit la carte intérieure. Ce tableau est [longitude, latitude].

Ensuite, il y a un tableau de niveaux. Vous pouvez avoir plusieurs étages par bâtiment. Nous en avons seulement conçu un, c'est donc celui que nous avons défini dans le tableau. Placez ces deux fichiers dans un dossier et créez un fichier ZIP à partir du dossier. Ensuite, rendez-vous sur https://mapdesigner.wrld3d.com/indoormap/latest et commencez à créer une carte!

Cliquez sur Nouvelle carte intérieure et nommez-la. Ensuite, recherchez le bâtiment approprié, en utilisant la latitude et la longitude. Lorsque vous voyez le bâtiment que vous voulez, cliquez dessus et cliquez sur Revendiquer les bâtiments. Assurez-vous de prendre l'option Télécharger le plan d'étage, car cela facilitera le suivi dans QGIS dans un instant. Ensuite, passez à l'étape Upload Map et téléchargez le fichier ZIP que vous avez créé. Ça va prendre quelques instants à traiter. Une fois que vous avez réussi, vous devriez voir un bouton sur la carte pour cliquer sur. En cliquant dessus il vous prendra à l'intérieur du bâtiment …

 À l'intérieur du bâtiment

Comme vous pouvez le voir, j'ai pris un moment pour comprendre que les coordonnées étaient "longitude , latitude "au lieu de" latitude, longitude ". Lorsque vous êtes satisfait de la carte intérieure, cliquez sur Rendre la carte publique.

Il y a un guide plus long et plus détaillé pour créer ces cartes ici . J'ai trouvé certaines parties inutiles, mais votre kilométrage peut varier …

Interaction avec les cartes d'intérieur

L'approbation de votre carte peut prendre un certain temps. En attendant, regardons comment nous pouvons interagir avec les cartes intérieures.

Pour cette partie du tutoriel, nous allons travailler avec du code hébergé sur CodePen. Les CodePens sont démonstratifs et les meilleurs résultats seront obtenus en utilisant les extraits de code et les étapes de l'article. Si vous souhaitez une installation locale, recherchez des détails sur la façon de le configurer dans le tutoriel précédent .

Commençons par créer une carte et entrer dans un bâtiment préfabriqué:

 const map = L.Wrld.map ("map", "f24b71dd92ab9e38cf4aa53806ab813d", {
    centre: [56.459801, -2.977928],
    zoom: 15,
    indoorsEnabled: true,
})

map.indoors.on ("indoormapenter", () => {
    map.indoors.setFloor (2)
    map.setView ([56.459984, -2.978238]20)
})

map.on ("initialstreamingcomplete", () => {
    map.indoors.enter ("westport_house")
})

Ceci est tiré de CodePen

Dans cet exemple, nous passons aux coordonnées des bureaux de WRLD. Une fois la carte terminée (via initialstreamingcomplete ), nous demandons à la carte de "rentrer à l'intérieur". Dans l'événement indoormapenter nous définissons l'étage sélectionné sur 2 et zoomons plus loin sur la carte.

Cela fonctionnera avec les cartes que vous avez soumises, une fois ils ont été approuvés.

Nous pouvons interagir avec les fonctionnalités en écoutant un événement click:

 map.indoors.on ("indoorentityclick", (event) => {
    map.indoors.clearEntityHighlights ()
    map.indoors.setEntityHighlights (event.ids [0][255, 0, 0, 128])
})

Ceci est de CodePen

Le indoorentityclick reçoit un événement qui contient l'ID de l'entité sur laquelle on clique. Nous pouvons utiliser les événements clearEntityHighlights et setEntityHighlights pour faire basculer les couleurs personnalisées sur les entités que nous voulons mettre en évidence.

Il est probablement temps pour une autre citation …

J'ai vu des Crashers de mariage accidentellement. J'ai acheté un billet pour "Grizzly Man" et suis allé dans le mauvais théâtre. Après une heure, je me suis dit que j'étais dans le mauvais théâtre, mais j'ai continué à attendre. Parce que c'est la chose à propos des attaques d'ours … ils viennent quand on s'y attend le moins. – Dwight … encore

Création d'un motif de surbrillance répétable

Essayons une expérience. Faisons un bouton "enregistrer" qui enregistre les clics que nous faisons sur la carte; puis les rejette tous. Nous aurions besoin d'un bouton d'enregistrement et de lecture, ainsi que d'un tableau de clics …



Ceci vient de CodePen

Maintenant, connectons ces boutons avec les événements click:

 map.indoors.on ("indoorentityclick", (event) => {
    map.indoors.clearEntityHighlights ()
    map.indoors.setEntityHighlights (event.ids [0][255, 0, 0, 128])

    clicks.push ({
        heure: nouvelle Date (),
        id: event.ids [0]
    })
})

Laisser l'enregistrement = false
laissé commencé = null
cliquetis = []

const record = document.querySelector ("# enregistrement")
const play = document.querySelector ("# play")

record.addEventListener ("clic", () => {
    if (enregistrement) {
        enregistrement = faux
        record.innerText = "record"
    } autre {
        enregistrement = vrai
        record.innerHTML = "stop"
        commencé = nouvelle Date ()
        clics = []
    }
})

play.addEventListener ("clic", () => {
    map.indoors.clearEntityHighlights ()

    pour (clic sur les clics) {
        setTimeout (() => {
            map.indoors.clearEntityHighlights ()
            map.indoors.setEntityHighlights (click.id, [255, 0, 0, 128])
        }, click.time.getTime () - started.getTime ())
    }
})

Ceci vient de CodePen

Regardons d'abord l'événement du bouton d'enregistrement. Lorsque vous cliquez dessus, si l'enregistrement n'a pas encore commencé, nous modifions la valeur du texte du bouton à stop et nous effaçons le tableau des clics. Nous capturons également le moment auquel le bouton d'enregistrement a été cliqué, afin que nous puissions chronométrer nos événements par rapport à celui-ci.

Si on clique dessus à nouveau, on peut réinitialiser la valeur du texte du bouton et arrêter l'enregistrement.

Puis, quand on clique sur le bouton de lecture; nous effaçons toutes les fonctionnalités en surbrillance et commençons à parcourir les événements «enregistrés». Ils sont dans un tableau, donc nous pouvons utiliser un pour ... de loop. Nous définissons un délai d'attente pour chaque événement de clic en prenant l'heure du clic et en soustrayant le temps commencé de celui-ci. Tous les délais d'attente sont créés pratiquement en même temps, mais ils sont déclenchés par rapport à la durée après le début de l'enregistrement.

Enfin, nous devons capturer les événements de clic lorsque les fonctions sont cliquées. Ainsi, nous détournons notre écouteur d'événement indoorentityclick en ajoutant les événements click au tableau de clics . Essayez-le, en enregistrant quelques clics puis en les rejouant. C'est assez addictif …

 Mettre en évidence les fonctionnalités

Créer un calendrier

Développons cette idée pour inclure un programme configurable. Disons que quelqu'un à WRLD se déplace dans le bureau, pendant la journée. Ou, imaginez (en accord avec notre thème) que Dwight voulait suivre les mouvements de Jim …

Il pourrait le faire s'il connaissait l'emploi du temps de Jim:

 const schedule = [
    {
        "start": "08:00",
        "duration": "00:30",
        "id": "0003"
    },
    {
        "start": "08:30",
        "duration": "00:30",
        "id": "0004"
    },
    {
        "start": "09:15",
        "duration": "00:45",
        "id": "0028"
    },
    {
        "start": "10:00",
        "duration": "01:00",
        "id": "Meeting Room"
    },
    {
        "start": "12:00",
        "duration": "01:30",
        "id": "0039"
    }
];

Ceci est de CodePen

Nous pouvons faire une fonction qui calcule le nombre de minutes pour le format d'heure que nous utilisons (ie 01:30 90 ):

 const timeToMinutes = (heure) => {
    laissez holder = new Date ();

    holder.setHours (0);
    holder.setMinutes (0);
    const start = holder.getTime ();

    const parties = time.split (":");

    holder.setHours (parseInt (parties [0]10));
    holder.setMinutes (parseInt (parties [1]10));
    const end = holder.getTime ();

    retour (fin - début) / 1000/60;
}

Horaire de const = [
    // ...
]

pour (laisser événement de calendrier) {
    console.log (timeToMinutes (event.duration))
}

Ceci est de CodePen

Cela va imprimer 30 30 45 60 , et 90 dans l'ordre. Ensuite, nous devons ajouter ces minutes à l'heure de début, pour savoir quand l'heure de fin est:

 const timeToMinutes = (time) => {
    // ...
}

const startFromTime = (heure) => {
    const parties = time.split (":");

    laissez holder = new Date ();
    holder.setSeconds (0);
    holder.setHours (parseInt (parties [0]10));
    holder.setMinutes (parseInt (parties [1]10));

    porte-retour;
}

const endFromStartAndMinutes = (début, minutes) => {
    return new Date (start.valueOf () + (minutes * 1000 * 60));
}

Horaire de const = [
    // ...
]

pour (laisser événement de calendrier) {
    const start = startFromTime (événement.start)
    const minutes = timeToMinutes (event.duration)
    const end = endFromStartAndMinutes (début, minutes)

    console.log (début, fin)
}

Cela vient de CodePen

… Et cela enregistrera les heures de début et de fin par rapport au jour actuel. Vous pouvez vouloir que les heures de début et de fin soient relatives à un jour fixe, donc vous devez modifier startFromTime et endFromStartAndMinutes pour prendre une journée en compte.

heures de début et de fin, nous pourrions coder la carte intérieure pour afficher la pièce où ce membre du personnel est en ce moment:

 const schedule = [
    // ...
]

setInterval (() => {
    map.indoors.clearEntityHighlights ();

    pour (laisser événement de calendrier) {
        const start = startFromTime (événement.start);
        const minutes = timeToMinutes (event.duration);
        const end = endFromStartAndMinutes (début, minutes);

        const now = new Date ();

        if (now> = start && maintenant <= end) {
            console.log ("L'heure est maintenant" + now.toLocaleTimeString () +
                        ", dans le" + start.toLocaleTimeString () +
                        "to" + end.toLocaleTimeString () +
                        "intervalle, entité de mise en surbrillance" + event.id);
            map.indoors.setEntityHighlights (event.id, [255, 0, 0, 128]);
        }
    }
}, 1000);

Cela vient de CodePen

En comparant l'heure actuelle aux heures de début et de fin de chaque événement; nous pouvons dire à quel événement le membre du personnel se trouve actuellement (et mettre en surbrillance la fonction en conséquence).

Si vous ne voyez aucune entité en surbrillance, vous n'en avez probablement pas prévu pour l'heure exacte où vous regardez le code . Essayez d'ajuster la planification de ce CodePen et ouvrez la console pour voir quelle entité doit être mise en surbrillance. J'ai également enlevé le code d'enregistrement / lecture des exemples précédents, pour qu'il soit plus facile de voir ce qui se passe dans cette démo.

Pensez simplement à comment cela pourrait être étendu. Vous pouvez ajouter les horaires de chacun pour créer un système de réservation d'événement virtuel. Ou, vous pouvez créer une visualisation animée pour voir s'il y a des conflits. Ceci est aussi un autre point de départ pour une application.

Résumé

Nous avons passé beaucoup de temps à apprendre les tenants et les aboutissants de la création de cartes intérieures. WRLD n'est pas la seule plate-forme qui comprend les cartes créées par QGIS, donc c'est une bonne compétence à apprendre si vous voulez faire toutes sortes de mapping.

Nous avons aussi regardé comment les cartes QGIS sont importées et utilisées dans le WRLD Plate-forme. Nous pouvons définir des cartes avec énormément de détails et interagir avec eux en temps réel. Une fois que vous savez quoi installer et comment dessiner des fonctions, la cartographie intérieure est assez simple.

Prenez le temps de réfléchir à la façon dont vous pourriez utiliser ceci, pour modéliser votre maison ou votre bureau. Peut-être pourriez-vous utiliser les cartes intérieures, en conjonction avec d'autres fonctionnalités de la brochure, pour créer des cartes de flux de chaleur ou des cartes d'utilisation de l'énergie par salle. Peut-être pourriez-vous créer votre propre application de planification de bureau

Je devrais mentionner: si vous voulez travailler sur des cartes intérieures personnalisées mais que vous n'avez pas envie de les concevoir vous-même, WRLD offre un service de cartographie intérieure un frais. Je n'ai pas expérimenté les niveaux supérieurs de service et de fonctionnalité, mais il semble que le WRLD soit assez flexible quant à la façon dont les cartes intérieures 3D sont rendues publiques (pour les stades et les aéroports) par rapport au privé (hôpitaux et écoles ). Suite à ce tutoriel, ils m'ont également dit qu'ils cherchent à simplifier la documentation et le flux de travail pour la création de cartes intérieures. C'est un peu détaillé en ce moment, mais ça vaut bien les résultats si vous me le demandez. Imaginez si c'était encore plus facile à faire …

Nous sommes à la fin de notre voyage WRLD. C'est devenu l'un de mes services intégrables préférés. C'est amusant de travailler avec et peut être assez détaillé et flexible. De plus, je n'ai pas payé un centime pour l'utiliser. J'espère que vous avez eu autant de plaisir à suivre ces tutoriels que je les ai écrits. Faites-moi savoir ce que vous avez construit sur Twitter . Vous pouvez également contacter WRLD avec des questions ou pour leur montrer ce que vous avez construit.






Source link