Je m'étais loupé sur les maxZoomLevel
Je m'étais loupé sur les maxZoomLevel
Nos deux messages se sont croisés. Et je n'ai pas vu ta question lors de mon envoi précédent.
Voici mes réflexions. En effet, les étiquettes s'affichent. Mais mon souhait est qu'elles disparaissent automatiquement quand le niveau de zoom est haut ou bas, au dela ou en deça de minZoomLevel et maxZoomLevel.
Sinon, dans un cas (petit zoom), les étiquettes se chevauchent et c'est TRES TRES nul.
Ou pour un grand zoom, elles deviennent inutiles car hors contexte. A la limite pour ce cas, le problème d'affichage est moins important, et je chipote.
Effectivement en passant en zoom entre Dépt et Pays, la couche "Didier" n'est plus active mais les popups sont toujours présents et se recouvrent.
Mais il me semble que dans ce cas il faudrait passer par les "Strategy" pour regrouper les marqueurs cf http://geotribu.net/node/47
effectivement, il reste bien ce pb...
Effectivement, ce problème doit être résolu sinon c'est non présentable. Convenez-en! Mais pour la solution Strategy de mga_geo, même si je comprends son objectif, je suis incapable (du fait de ma nullité en JS) d'y participer activement... J'attends donc que mga_geo s'y colle et nous sort une adaptation de geotribu... Désolé.
La solution Strategy peut résoudre les problèmes quand les "étiquettes" sont agrégables. Mais quand ces étiquettes ne le sont pas (cas d'informations localisés mais non généralisables), il faut simplement qu'elles disparaissent quand le niveau zoom dépasse une valeur fixée.
la stratégie de clustérisation est pratique pour regrouper plusieurs éléments en un ("plus gros" typiquement)...j'avais fait des tests il y a quelques mois pour voir si cela pouvait solutionner les pb de performance sur des chargements de gros KML
par contre, on n'a plus accès aux caractéristiques individuelles de chaque élément...juste au nombre d'éléments regroupés...du moins en version OL 2.7...je ne sais pas si c'est identique en 2.8.
Sur le principe de base, le cluster fonctionne sur l'aggrégation de données vecteur basée sur la distance des centres des emprises des objets à aggréger. Si cela fonctionne bien dans le cas de ponctuel (pour des labels), cela est beaucoup moins efficace pour des données linéaires et surfaciques (pour cela il existe des distances spéciales ...). Au passage, la fonction de distance euclidienne qui n'est vraiment pertinente qu'à grandes échelles ... Une évolution serait de surchager la méthode shouldCluster() ...
Comme l'écrit Unusual, on perd les caractéristiques individuelles. Dans le cas de labels, l'aggrégation devient quoi ? Pour fonctionner, il faudrait alors définir des ordres d'importances sur les labels en fonction de certains critères sur les données initiales et lors de l'aggrégation utiliser cette fonction d'importance pour afficher l'objet final ... C'est de la cartographie!
Je pense qu'il vaut mieux jouer simplement avec les échelles d'affichages ET choisir les labels à affichés.
Comme c'est bien dit: Simple et logique. Mais concrètement?Je pense qu'il vaut mieux jouer simplement avec les échelles d'affichages ET choisir les labels à afficher.
Je pourrai paraitre entêté, ou idiot, mais tout cela est du à ma grande ignorance en js.
1/ Il me semblait que minZoomLevel et maxZoomLevel encadraient la visibilité des couches en fonction du zoom. Je l'ai d'ailleurs vérifié dans des cas simples.
2/ Pourquoi donc dans la séquence de l'étape 4 de dgrichard,
alors que "kt" charge bien une couche avec les paramètres minZoomLevel et maxZoomLevel, ceux-ci désactivent bien la couche en question quand on est à l'extérieur de l'encadrement, mais ne la rend pas invisible? Alors que la couche "labely" (de l'étape 1) répond bien à ces deux attentes (désactivation et invisibilité). Ma page de test est ici
Code : Sélectionner tout - Visualiser dans une fenêtre à part var kt=viewer.getMap().addLayer("KML"....
Faute d'avoir une réponse à cette question déjà posée, j'ai essayé de contourner le problème avec une détection de zoomend comme le suggère mga_geo dans son exemple emprise suivi d'un effacement de la couche...
A ces propos très peu orienté objet, je vous laisse imaginer mes soucis avec firebug.Mais à force de telle manip et de questions stupides sur ce forum (avec l'aide de dgrichard, mga_geo, unusual, mick helley, etc.), je devrai pouvoir écrire quelques lignes de code?
![]()
Je suis désolé, mais je ne comprends pas ...
Qu'est-ce qui ne marche pas ?
- les labels s'affichent dans leur plage d'échelles (affichés, masqués);
- les KML s'affichent dans leur plage d'échelles (affichés, masqués);
- les labels portent sur les données KML : leur plage d'affichage est, à minima, celle des KML :
Code : Sélectionner tout - Visualiser dans une fenêtre à part KML.minZoomLevel<=labels.minZoomLevel<=labels.maxZoomLevel<=KML.maxZoomLevelC'est le code que j'ai proposé qui semblait répondre à la question initiale.
- Quand la couche KML ne s'affiche plus, les labels disparaissent;
- Les labels sont invisibles de la liste des couches.
Il faut ensuite le lire, l'analyser, le comprendre, l'améliorer pour pouvoir écrire à son tour du code. C'est un long apprentissage.
Le mieux est toujours l'ennemi du bien, surtout en programmation. Il faut faire simple et augmenter en fonctionnalité en restant simple.
- Choisir les échelles d'affichage : c'est juste paramètrer minZoomLevel/MaxZoomLevel pour afficher/masquer les données et labels - aucune programmation ;
- Choisir le contenu des labels : c'est choisir les champs à mettre dans le label. Puis, quant c'est satisfaisant, on rajoute de l'intelligence dans cette méthode : choix des champs en fonction de l'échelle (zoom), des propriétés intrinsèques des objets, changement de modalités de la géométrie du label. Mon code, utilise le milieu de l'emprise de l'objet, mais le code peut être différent suivant le zoom ... C'est la partie où il est nécessaire de s'approprier le code exemple.
Soyons précis.
- Sur ma page test, on aperçoit deux labels portant le nom des deux départements sur fond orange: Haute-Loire (43) et Ardèche (07). Les vois-tu? Ces deux labels sont portés par la couche kt en référence à ton exemple donné..
- Cette couche est paramétrée avec
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 MinZoomLevel:9, maxZoomLevel:11
- Or, quand on zoome à très petite échelle, la couche kt se désactive bien (normal), mais les labels se maintiennent à l'écran (en se chevauchant), alors qu'il me semble qu'ils devraient disparaitre, comme tu le dis d'ailleurs
c'est juste paramètrer minZoomLevel/MaxZoomLevel pour afficher/masquer les données et labels - aucune programmation ;- Si mes propos ne sont pas encore assez clairs, ne te torture pas de trop à me répondre. J'attendrai, avec impatience, la mise en ligne de ton exemple lors de la prochaine MAJ (pour quand?), pour tester et enlever certaines incertitudes...
J'ai l'impression que les labels sont rattachés à une couche KML qui est toujours elle affichée (0743popup.kml, les limites des départements 07 et 43). Le problème semble donc plutôt être là, bien qu'elle soit déclarée entre 9 à 11, elle s'affiche sauf aux grandes échelles, mais là les labels restent ...
C'est peut-être un boggue dans l'étape 3 où kt ne lance jamais l'évènement "onchange" ...
Il faut creuser :
- Laisse le menu des couches affiché pour voir s'il y a un lien avec celui-ci (dans mes tests, le gestionnaire de couches est présent) ;
- Ensuite, coche/décoche la couche "popup" pour voir si les labels suivent.
Pour la date, j'espère que dans la semaine du 22 au 29 juin, la version sera mise en production.
Je suis assez content que tu te rallies à ma position. Cela veut dire qu'il y a effectivement un problème
Voici ma nouvelle page test avec le menu des couches
Je constate:
- Aucun lien avec ce menu dans l'affichage des étiquettes en question.
- La sélection ou non de la couche popup agit bien sur l'affichage des étiquettes
Le problème est ailleurs, mais je ne suis pas encore assez doué pour remonter à l'origine du problème. Surtout si je n'ai pas sous les yeux un exemple qui "marche".
En reprenant l'essai de mga_geo , je renifle (sauf erreur de ma part) le même problème. Sa couche "didier" introduite par la variable kt a pour paramètremais ses 4 étiquettes NW, NE, SW, SE se maintiennent toujours quand le zoom est >16 ou <10, alors que la couche "didier" se désactive correctement. Il me semble.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 minZoomLevel: 10, maxZoomLevel: 16
Je viens de mettre à jour ma page basée sur le code de Didier pour obtenir un résultat plus conforme.
En plus de la propriété visibilty, je teste inRange.
J'ai cherché sur Google le code source de LayerSwitcher.js pour comment faire
http://trac.openlayers.org/browser/s...yerSwitcher.js
Suite à son message, j'ai repris le "module de synchronisation" (dénommé: étape 3 par dgrichard dans sa proposition de codage) de mga_geo donné dans http://atlasnw.free.fr/web/geoportai...ml_didier.html (légèrement différent de celle de dgrichard) et je constate que les étiquettes/labels disparaissent bien (enfin!) en dehors de la plage minZoomLevel-maxZoomLevel. Ne me demandez surtout pas pourquoi: j'en suis incapable.
De mon coté donc, problème résolu..... jusqu'à la prochaine merdouille...
Désolé pour mon manque d'intervention, mais je suis à l'étranger ...
Le problème est en fait lié à la non-prise en charge de l'évènement "zoomend". J'ai corrigé mon exemple et vous l'enverrai ce week-end à mon retour sur le sol national !
Pour que les labels soient synchronisés avec la couche qu'ils décrivent, mais aussi les zooms il faut modifier le code que j'avais proposé comme suit :
- Etape 1 (création de la couche labels) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 var labely= new OpenLayers.Layer.Vector( "labels", { styleMap: new OpenLayers.StyleMap({pointRadius:0}), // don't display points projection: OpenLayers.Projection.CRS84, minZoomLevel: 3, maxZoomLevel: 9, displayInLayerSwitcher:false, //hide labels from layers switcher visibility: false, onFeatureInsert: function(f) { var createPopup= function() { var label= "<div style='background-color:#FFFF00;"+ "border:thin solid black;"+ "font-family:\"Courier New, monospace\";"+ "font-size:12px;"+ "font-weight:bold;"+ "color:#000000;'>"+ this.attributes.name+ "</div>"; var popup= new OpenLayers.Popup.Anchored( null,this.geometry.getBounds().getCenterLonLat(),null,label); popup.autoSize= true; popup.backgroundColor= "transparent"; this.popup= popup; return this.popup; }; f.createPopup= OpenLayers.Function.bind(createPopup,f); } } ); VISU.getMap().addLayer(labely);
- Etape 2 (peuplement des labels à partir des données origines) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 var kt= viewer.getMap().addLayer("KML", "kml", "url du kml", { onFeatureInsert:function(f){}, //default OpenLayers : do nothing eventListeners:{ featuresadded: function populateLabels(e) { if (e==null) { return;} var f= null, fi= null, gi= null; for (var i= 0, l= e.features.length; i<l; i++) { fi= e.features[i]; gi= fi.geometry.getBounds(); f= new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point((gi.left+gi.right)/2, gi.bottom), { name:fi.attributes.name }); labely.addFeatures([f]); f.createPopup(); if (labely.visibility) { f.layer.map.addPopup(f.popup); } } } }, visibility:false, minZoomLevel: 0, maxZoomLevel:10 }, { onSelect:openWikipediaPopup, onUnselect:function(f){} //default OpenLayers : do nothing } );
- Etape 3 (lier les labels à leur couche originie pour faciliter le travail de synchronisation) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 labely.labeledLayer= kt;
- Etape 4 (synchroniser) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 labely.map.events.on({ "changelayer": synchronizeVisibility, "zoomend" : synchronizeVisibility, scope : labely});
- Etape 5 (la synchronisation) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 function synchronizeVisibility(e) { //synchronize visibility with KML //loading KML may take some time, ... //all labels may not appear the first time ! if (e==null) { return;} if ((e.type=="changelayer" && e.layer==this.labeledLayer && e.property=="visibility") || (e.type=="zoomend")) { var i, l, f, p; this.inRange= this.calculateInRange(); this.visibility= this.labeledLayer.visibility && this.inRange; this.display(this.visibility); this.redraw(); if (!this.visibility) { // hide popups if not visible for (i= 0, l= this.features.length; i<l; i++) { f= this.features[i]; p= f.popup; if (p) { p.hide(); } } } else { // show/create popups if visible for (i= 0, l= this.features.length; i<l; i++) { f= this.features[i]; p= f.popup; if (p) { if (OpenLayers.Util.indexOf(this.map.popups,p)==-1) { f.layer.map.addPopup(f.popup); } p.show(); } } } } }
- Pour rappel sur le code de la fonction openWikipediaPopup() qui ouvre une nouvelle fenêtre sur un clic :
Bien sûr, les combinaisons avec les OpenLayers.Strategy.* peuvent aussi être utilisées lors du peuplement des labels!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 function openWikipediaPopup(f) { if (f) { //get Extendata/Data[name="url"]/value : window.open(f.data.url.value,"Wikipedia","width=750,height=350,menubar=no,status=no,scrollbars=yes,resizable=yes"); this.unselect(f); } }
DGRichard, merci beaucoup pour votre engagement.
Correction faite et testée... Sous ff3, ok. Par contre sous IE6, une erreur apparait à la fin de l'étape 2 ("Identificateur, chaine ou nombre attendu" d'après la console d'erreur du navigateur) bloquant le chargement de l'api...
Cela est vrai pour http://43.lignon.free.fr/ign4/index7.htm qui contient votre nouvelle version de synchronisation. Par contre avec votre version précédente (contenant le problème de synchronisation) visible à http://43.lignon.free.fr/ign4/index6.htm, il n'y a pas d'erreur sous IE6.
Sinon, je me demande ce que ce codage deviendra avec la nouvelle MAJ de l'API prévue pour ces jours-ci? Sera-ce intégré dans l'API?
C'est juste une erreur de recopie de mon code :
La virgule est en trop !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 onUnselect:function(f){}, //default OpenLayers : do nothing
Pour la mise en ligne, mon équipe m'a remonté des boggues qu'il me faut corriger ... L'exemple sera dans l'API (geoportalMap_kml.html).
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager