web-dev-qa-db-fra.com

Affichage dans un navigateur d'un plan d'étage 2D interactif utilisant html5 et javascript

Je dois remplacer la visionneuse Flash que j'ai construite il y a des années pour afficher des plans d'étage 2D interactifs provenant d'AutoCAD.

Actuellement, les fichiers AutoCAD sont lus et convertis en fichiers XML contenant les [~ # ~] x [~ # ~] et [~ # ~] y [~ # ~] coordonnées des polygones représentant les objets du plan d'étage: pièces, murs, actifs, etc. Les objets du dessin sont cliquables et peuvent être définis comme visibles ou non selon les vues thématiques .

Parfois, ces plans d'étage peuvent être relativement gros, avec beaucoup de points .

J'ai déjà essayé d'utiliser un contrôle de carte Web comme LeafletJS car il a déjà la fonctionnalité PAN et ZOOM, je peut insérer des marqueurs cliquables et gérer les couches afin que je puisse afficher ou masquer des objets par une vue thématique. J'ai défini la carte CRS comme métrique et je charge les données comme GeoJSON Malheureusement, avec des plans d'étage de taille moyenne dans le monde réel, c'est trop lent et parfois devenu ne répond pas .

L'exemple ci-dessous est composé de 18630 ​​objets linéaires et n'est pas très réactif lors du panoramique.

enter image description here

Alors maintenant, je voudrais dessiner directement le plan d'étage dans le navigateur en utilisant [~ # ~] svg [~ # ~] ou [~ # ~] toile [~ # ~] . Je préfère utiliser [~ # ~] canvas [~ # ~] car il est beaucoup plus rapide que SVG, en utilisant également WebGL si pris en charge, mais je dois compter sur une bibliothèque afin d'avoir des gestionnaires d'événements et une gestion d'objet facile comme un DOM.

Alors maintenant, je demande si une bibliothèque comme threeJS peut gérer facilement une tâche comme celle-ci, même si j'ai besoin de mapper des objets 2D et si c'est le la bonne technologie à choisir. En particulier, est-ce possible avec threeJS:

  1. Pour affecter l'écouteur d'événements aux objets pour obtenir leurs ID?
  2. Pour appliquer des règles CSS3 aux objets de style, par exemple, pour mettre en évidence une pièce ou une table?
  3. ThreeJS peut facilement dessiner à la fois sur des éléments SVG ou Canvas?
  4. Avec ThreeJS, je peux également gérer facilement le panoramique et le zoom?
  5. Peut-il s'afficher également sur les appareils mobiles ? (Android et iOS)

Si quelqu'un connaît une meilleure bibliothèque ou technologie pour accomplir cette tâche, je suis totalement libre de toute suggestion.

(Veuillez noter que je n'ai besoin que de dessins 2D car la 3D a déjà été construite avec d'autres technologies de Revit)

7
Giox

En utilisant webgl (via three.js par exemple), vous pouvez dessiner des millions de primitives de ligne simples à 60 ips sur les navigateurs de bureau compatibles GPU.

Voici un exemple artificiel de plus d'un million de primitives de ligne, regroupées à l'aide de three.js:

https://codesandbox.io/s/0pp3x92n4p

et ici:

http://vectorslave.com/wireblueprint/index.html

enter image description here

Here is a version using your sample data, duplicated 100x to create approx 1.8 million lines

2
manthrax

Suite à la suggestion de feeela, j'ai implémenté la visualisation en SVG, en dessinant le même modèle composé de 18630 ​​lignes.

Il se charge nettement plus rapidement que la carte métrique GeoJSON Leaflet.

Le SVG est fourni par une API interrogeant le bâtiment et le sol, et il renvoie l'architecture sous forme d'éléments (texte/simple) que j'ajoute à l'élément dans ma page Web.

Pour ajouter des éléments de chemin de chaîne à l'élément DOM SVG que j'ai utilisé bibliothèque parseSVG .

Je n'ai pas trouvé de support "natif" pour pan et zoom , j'ai donc utilisé une bibliothèque jQuery: Ariutta SVG Pan and Zoom

Avec Ariutta SVG pan & zoom, je devrais être capable d'écouter également des événements mobiles comme pincer et toucher .

Voici le code javascript:

<div id="mapArea">
     <svg id="map" xmlns="http://www.w3.org/2000/svg" x="0" y="0" style="stroke: #00ff00; stroke-width: 0.2px;background:#000">
     </svg>
</div>

<script type="text/javascript">
    var container = document.getElementById('mapArea'),
        width = container.offsetWidth,
        svgMap = document.getElementById('map');

    svgMap.setAttribute('width', width);
    svgMap.setAttribute('height', width * 0.5);

    $(document).ready(function () {

        $.ajax({
            type: "GET",
            url: "/Public/GetSVGPlan.aspx?building=1423&floor=3",
            dataType: "text",
            success: function (result) {
                svg = parseSVG(result);
                svgMap.appendChild(svg);
                svgPanZoom('#map', {
                    zoomEnabled: true,
                    controlIconsEnabled: true,
                    fit: true,
                    center: true
                });
            },
            error: function (error) {
                console.log(error);
            }
        });
    });
</script>

Les éléments de chemin renvoyés par l'API sont les suivants:

<path d="M173.7043 66.758, L173.7054 66.7701" />
<path d="M191.947 64.2563, L191.9198 63.9453" />
<path d="M129.3072 12.2843, L129.3301 12.3702" />
<path d="M129.3301 12.3702, L131.701 11.735" />
<path d="M191.6087 63.9725, L191.636 64.2836" />
<path d="M173.7054 66.77, L172.5553 66.9803" />
<path d="M131.3573 11.735, L129.3072 12.2843" />
<path d="M195.8466 63.9148, L195.8194 63.6037" />
<path d="M172.5553 66.9803, L172.6882 66.9687" />
<path d="M129.3074 12.2841, L129.2449 11.7366" />
<path d="M195.7694 63.6081, L195.8194 63.6037" />
<path d="M172.6882 66.9687, L173.7064 66.7821" />
<path d="M129.2451 11.7368, L129.2451 9.5381" />
<path d="M195.5083 63.631, L201.43 63.1124" />
<path d="M226.9927 14.458, L228.0006 14.4593" />
<path d="M173.7064 66.7821, L173.7075 66.7942" />
<path d="M129.2451 9.5381, L131.6964 9.5381" />
<path d="M201.4572 63.4235, L195.5356 63.9421" />

et les résultats:

enter image description here

Activé Internet Explorer 11 est très lent, utilisant beaucoup de CPU sur le processus de rendu pendant environ 15 secondes. Je pense que cela est dû plus à la boucle js pour ajouter les éléments de chemin qu'au rendu SVG.

Sur mobile ( Chrome sur Android ) a une bonne réponse et une charge rapide/rendu (~ 3-5s)

Même si cela fonctionne comme prévu, toute suggestion pour améliorer les performances est la bienvenue !!

1
Giox