OpenLayers 3: Comment actualiser la carte après avoir changé le style d'une entité?


9

J'ai une carte OpenLayers 3.2.0 qui présente des sources vectorielles ( ol.source.Vector) et des couches vectorielles associées ( ol.layer.Vector)

Lorsque les fonctionnalités ( ol.Feature) sont ajoutées aux sources vectorielles, une datapropriété leur est affectée, définie sur l'objet javascript que la fonctionnalité représente. TypeScript suit ...

vectorSource.addFeature(new ol.Feature({
    geometry: /* ... */,
    data: vectorData,
}));

Les couches vectorielles ont alors une fonction de style qui lit la datapropriété et récupère son style:

vectorLayer = new ol.layer.Vector({
    source: vectorSource,
    renderBuffer: /* ... */,
    style: function (feature: ol.Feature, resolution: any) {
        var data = </* TypeScript Type */>feature.get('data');
        if ((data) && (data.style)) {
            return [data.style];
        }
        else {
            /* return default style */
        }
    }
});

Parfois, des événements sans rapport avec la carte font changer les styles. Par exemple, lorsqu'un objet devient invalide, son style change. De toute évidence, data.styleétant entièrement sous mon contrôle, le changer est trivial.

Le problème est que la carte ne sait pas que le style a changé. Si je modifie le style d'un objet, puis fais un zoom sur la carte, le forçant à être redessiné, je remarque que mes fonctions de style s'exécutent et renvoient le nouveau style et la fonction est redessinée. Comment forcer par programmation la carte à se rafraîchir?

Après quelques recherches et expérimentations, j'ai essayé:

  1. Faire appel render()à ol.Maplui - même.
  2. Appel dispatchChangeEvent()à laol.source.Vector
  3. Appel redraw()à laol.layer.Vector

Celles-ci ont été suggérées mais aucune n'a fonctionné, ce qui n'est pas surprenant car seule la première méthode est même répertoriée dans la documentation de l'API OpenLayers 3.2.0 et elle n'est pas marquée comme stable.


avez-vous essayé vectorlayer.refresh ({force: true}); ?
ylka

J'ai mais, sans surprise, cela ne fonctionne pas parce que c'est une méthode OpenLayers 2.
Xharlie

Réponses:


12

Par hasard, je suis tombé sur la réponse - c'est d'appeler changed()les fonctionnalités elles-mêmes après avoir changé la stylepropriété de leurs données associées. Voir: http://openlayers.org/en/v3.2.0/apidoc/ol.Feature.html?unstable=true#changed

Cela nécessite que je garde une trace des ol.Featureobjets associés à chaque vectorDataobjet (auparavant, je n'avais besoin que de trouver le à vectorDatapartir d'une fonctionnalité, ce qui pouvait être fait avec get()), mais ce n'est pas très coûteux.

(J'ai trouvé cela en regardant setGeometryet setStyleet d'autres méthodes ol.Featurepour voir ce qu'ils font.)


Bien que cette approche fonctionne, appeler changedun nombre raisonnable de fonctionnalités entraîne en fait une pénalité de performance assez grave (écrasé Chrome plusieurs fois de cette façon). Je recommanderais d'appeler changed()la source de votre couche une fois que toutes vos fonctionnalités ont été modifiées.
Kyle

0

J'ai passé une semaine à essayer de comprendre comment faire disparaître une entité (Polygone) de la carte après l'avoir supprimée ( vectorSource.removeFeature(selectedFeature). Et aucune solution n'a fonctionné. Curieusement, l'OL3 v3.15.1 actuel n'a pas de fonction de rafraîchissement / rendu forcé de base qui La solution qui a fonctionné pour moi a été de changer selectedFeaturede style:

        var newStyle = new ol.style.Style({
            image: new ol.style.Circle({
                radius: 5,
                fill: new ol.style.Fill({color: 'red'}),
                stroke: new ol.style.Stroke({color: 'yellow', width: 1})
            })
        });
        selectedFeature.setStyle(newStyle)

Tout style fonctionnerait puisque la fonction a déjà été supprimée du calque mais n'a pas été actualisée.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.