Bonjour,
La béta5 apporte bien une gestion plus "normale" de la selection des calques photo/carte lors des changement de territoires (=~ projection) => un grand merci.
En revanche les choix effectués sur les couches WMS/WFS ne sont pas reportés !
Bonjour,
La béta5 apporte bien une gestion plus "normale" de la selection des calques photo/carte lors des changement de territoires (=~ projection) => un grand merci.
En revanche les choix effectués sur les couches WMS/WFS ne sont pas reportés !
C'est assez complexe de généraliser à n'importe quel type de couches ...
Globalement, voici le code que j'ai mis en place pour les couches Géoportail :
Les couches Géoportail visibles en projection locale et monde portent le même nom. Cette méthode repose sur cela.
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 // listen to changelayer, visibility change to synchronize local/world layers : map.events.register('changelayer',layer,function(e) { if (!e) { return; } if (!(e.property=='visibility' || e.property=='opacity')) { return; } if (e.layer===this) { return; } if (e.layer.getCompatibleProjection()==null) { return; }//must be displayable on current map if (e.layer.name!=this.name) { return; } var v= e.layer[e.property]; if (this.getCompatibleProjection()==null && v!=this[e.property]) { if (e.property=='visibility') { this.visibility= v; this.display(v); this.redraw(); } else { this.setOpacity(v); } // FIXME: when _FXX_territory_->_WSM_world_ all Geoportal are turned to false !? // FIXME: when _FXX_territory_->_WLD_world_ all Geoportal are turned to true/false var bls= this.map.getLayersBy("isBaseLayer",true); for (var i= 0, l= bls.length; i<l; i++) { var lyr= bls[i]; if (lyr===this.map.baseLayer) { continue; } if (this.getCompatibleProjection(lyr)!=null) { if (!this.savedStates[lyr.id]) { this.savedStates[lyr.id]= {}; } this.savedStates[lyr.id][e.property]= v; } } bls= null; } });
Pour d'autres couches (WMS/WFS), c'est lors du changement de baseLayer que le test s'effectue via l'interception de l'évènement "changebaselayer" ...
Pour les WMS :
Donc, la couche suit si et seulement si elle possède une projection compatible avec la nouvelle baseLayer ...
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 /** * APIMethod: changeBaseLayer * Listener of the map's event 'changebaselayer'. * Reproject its maxExtent according to the new * base layer if it is not a base layer itself. * * Parameters: * evt - {Event} the 'changebaselayer' event. * * Context: * layer - {<OpenLayers.Layer>} the new baseLayer * baseLayer - {<OpenLayers.Layer>} the old baseLayer * * Returns: * {Boolean} true to keep on, false to stop propagating the event. */ OpenLayers.Layer.WMS.Untiled.prototype.changeBaseLayer= OpenLayers.Layer.WMS.prototype.changeBaseLayer= function(evt) { if (OpenLayers.Layer.prototype.changeBaseLayer.apply(this,arguments)===false) { return false; } if (!this.isBaseLayer) { var p= this.getCompatibleProjection(evt.layer); if (p!=null) { this.projection= p; } this.setVisibility(false); } return true; };
Comme OpenLayers supporte la propriété projection pour la projection native de la couche, en regardant le code qui charge les capacités d'un service WMS, je me suis aperçu que les systèmes possibles sont "stockés" dans la propriété srs. Il suffit donc que celle-ci soit définie
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
36
37
38
39
40
41
42 /** * Method: getCompatibleProjection * Check whether the layer's projection is displayable with the base layer. * * Params: * blayer - {<OpenLayers.Layer>} the baseLayer to compare with. * if none, use current baseLayer from the map. * * Returns: * {<OpenLayers.Projection>} if compatible, undefined if not relevant, null on error. */ OpenLayers.Layer.WMS.Untiled.prototype.getCompatibleProjection= OpenLayers.Layer.WMS.prototype.getCompatibleProjection= function(blayer) { var lproj= OpenLayers.Layer.prototype.getCompatibleProjection.apply(this,arguments); if (lproj!=null) { return lproj; } if (blayer==null) { blayer= this.map.baseLayer; if (blayer==null) { return undefined; } } var bproj= blayer.getNativeProjection(); // assumption : from WMSCapabilities, srs is an array of // supported projections ... if (this.srs!==undefined && this.srs instanceof Array) { for (var i= 0, l= this.srs.length; i<l; i++) { var crs= this.srs[i]; if (!(crs instanceof OpenLayers.Projection)) { lproj= new OpenLayers.Projection(crs); } else { lproj= crs; } if (lproj.isCompatibleWith(bproj)) { return lproj; } lproj= null; } } return null; };
Même combat pour les WFS.
Pour les couches basées sur OpenLayers.Layer.Vector, je reprojette les données directement comme suit :
Pour les couches basées sur OpenLayers.Layer.Markers, je reprojette les données directement :
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 /** * APIMethod: changeBaseLayer * Listener of the map's event 'changebaselayer'. * Reproject its maxExtent according to the new * base layer if it is not a base layer itself. * * Parameters: * evt - {Event} the 'changebaselayer' event. * * Context: * layer - {<OpenLayers.Layer>} the new baseLayer * baseLayer - {<OpenLayers.Layer>} the old baseLayer * * Returns: * {Boolean} true to keep on, false to stop propagating the event. */ OpenLayers.Layer.GML.prototype.changeBaseLayer= OpenLayers.Layer.Vector.RootContainer.prototype.changeBaseLayer= OpenLayers.Layer.Vector.prototype.changeBaseLayer= function(evt) { if (OpenLayers.Layer.prototype.changeBaseLayer.apply(this,arguments)===false) { return false; } if (!this.isBaseLayer) { // force reloading the entire KML/GPX/etc to reproject it ... var v= this.getVisibility(); if (v) { this.setVisibility(false);//remove old locations; } if (!this.options) { this.options= {}; } if (!this.formatOptions) { this.formatOptions= {}; } if (!this.options.formatOptions) { this.options.formatOptions= {}; } var mapProj= this.map.getProjection(); var oldMapProj= evt.baseLayer? evt.baseLayer.getNativeProjection() : null; this.options.formatOptions.internalProjection= mapProj.clone(); this.formatOptions.internalProjection= mapProj.clone(); this.projection= mapProj.clone(); this.options.projection= mapProj.clone(); this.initResolutions();// force re-computing resolutions for (var i= 0, l= this.features.length; i<l; i++) { var feature= this.features[i]; feature.geometry.transform(oldMapProj,mapProj); if (feature.popup && feature.popup.lonlat) { feature.popup.hide(); feature.popup.lonlat.transform(oldMapProj,mapProj); } } if (v) { this.setVisibility(true);//reproject } } return true; };
Pour tous les autres types de couches, c'est activation/désactivation selon la compatibilité des projections...
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 /** * APIMethod: changeBaseLayer * Listener of the map's event 'changebaselayer'. * Reproject its maxExtent according to the new * base layer if it is not a base layer itself. * * Parameters: * evt - {Event} the 'changebaselayer' event. * * Context: * layer - {<OpenLayers.Layer>} the new baseLayer * baseLayer - {<OpenLayers.Layer>} the old baseLayer * * Returns: * {Boolean} true to keep on, false to stop propagating the event. */ OpenLayers.Layer.Text.prototype.changeBaseLayer= OpenLayers.Layer.GeoRSS.prototype.changeBaseLayer= OpenLayers.Layer.Boxes.prototype.changeBaseLayer= OpenLayers.Layer.Markers.prototype.changeBaseLayer= function(evt) { if (OpenLayers.Layer.prototype.changeBaseLayer.apply(this,arguments)===false) { return false; } if (!this.isBaseLayer) { var oldMapProj= evt.baseLayer? evt.baseLayer.getNativeProjection() : null; var mapProj= this.getProjection(); for (var i= 0, len= this.markers.length; i<len; i++) { var m= this.markers[i]; m.lonlat.transform(oldMapProj,mapProj); } } return true; };
J'espère avoir été complet
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