2
votes

openlayers 5 flash ennuyeux sur vector.getSource (). clear ()

Lorsque je charge plus de 500 fonctionnalités vectorielles dans Openlayers, les performances des tablettes et des téléphones diminuent considérablement. Ma solution a été d'effacer la source sur l'événement moveend de la carte. Cela fonctionne, mais se traduit par un flash gênant, vraisemblablement entre l'effacement et le rechargement de la source.

Une solution antérieure à ce "clignotant" ici ne fonctionne plus, cela entraîne des appels récursifs au WFS.

Voici mon code actuel:

XXX

Existe-t-il un moyen d'éviter le flash d'effacement / rechargement dans Openlayers 5? Ou y a-t-il une autre méthode que je devrais utiliser pour charger des couches vectorielles (les couches que j'ai sont généralement des couches ponctuelles avec 5000 à 10000 entités).

[EDIT] Après le commentaire de @ahocevar, voici le style que je J'utilise:

import {Style, Circle, Fill, Stroke} from 'ol/style';
import Defaults from './PointDefaults';

export default function() {
  return new Style({
    image: new Circle({
      radius: Defaults.radius,
      fill: new Fill({
        color: 'green',
      }),
      stroke: new Stroke({
        color: Defaults.strokeColor,
        width: Defaults.strokeWidth
      })
    }),
  });
}


3 commentaires

Le problème est probablement votre style . La réutilisation des objets de style est essentielle à de bonnes performances vectorielles. En cas de doute, modifiez votre question pour inclure également le style.


Je doute beaucoup :) J'ai ajouté le style; il est importé une fois, au moment de la création du calque.


Comme je le pensais. Vous créez de nouvelles images Circle avec chaque fonctionnalité. La taille par défaut du cache de style est de 32 images, donc avec plus de 32 fonctionnalités, les choses seront très, très lentes. J'ajoute une réponse qui montre comment vous devez écrire votre style.


3 Réponses :


1
votes

Ne pas effacer la source à chaque déplacement, mais seulement quand elle dépasse un nombre de fonctionnalités max , cela évitera des rechargements trop fréquents:

map.on('moveend', function(evt) {
  if (vectorSource.getFeatures().length > max) {
    vectorSource.clear()
  }
});

Les Openlayers devraient être en mesure d'afficher plus de 500 fonctionnalités, même sur des appareils lents.

  • Comme le dit ahocevar, le style peut être impliqué, voyons comment vous l'utilisez.
  • Vous pouvez également essayer d'utiliser l'option renderMode: 'image' pour la couche vectorielle pour un rendu plus rapide lors des interactions et des animations.
  • vous pouvez utiliser le clustering à grande échelle pour réduire le nombre d'entités à dessiner.

A titre d'exemple, ce site affiche plus de 18 000 points caractéristiques même sur les appareils mobiles: https: // c -conforme.fr


1 commentaires

Merci Jean-Marc; J'ai accepté la réponse d'Ahocevar, mais c'est également utile.



1
votes

Le problème est que vous créez un nouveau Style avec une nouvelle image Circle pour chaque entité à chaque image de rendu. Dans votre cas, vous n'avez même pas besoin d'une fonction de style, car le style est le même pour toutes les fonctionnalités. Donc, votre module style doit exporter le style, pas une fonction qui renvoie le style:

import {Style, Circle, Fill, Stroke} from 'ol/style';
import Defaults from './PointDefaults';

export default new Style({
  image: new Circle({
    radius: Defaults.radius,
    fill: new Fill({
      color: 'green',
    }),
    stroke: new Stroke({
      color: Defaults.strokeColor,
      width: Defaults.strokeWidth
    })
  })
});


2 commentaires

J'étais un peu pressé d'accepter la réponse. Les appareils mobiles ralentissent encore après le chargement d'environ 1000 fonctionnalités. Il semble que je doive trouver un moyen de limiter le nombre de fonctionnalités dans la mémoire de l'appareil qui évite également le flash causé par l'appel de vectorSource.clear ()


Vous devriez envisager d'utiliser des tuiles vectorielles au lieu de wfs. Ensuite, vous n'avez pas du tout à effacer les fonctionnalités.



0
votes

2 ans plus tard, j'ai trouvé une solution qui n'est pas vraiment "flashy", mais qui est un peu (je pense que ma formulation de la question a dû être trop vague).

J'utilise vectorSource.refresh ()

Donner ceci:

map.on('moveend', function(evt) {
 console.log('refreshing vector');
 vectorSource.refresh()
});

La version OpenLayers que j'utilise actuellement est la v6.5.0


0 commentaires