[Users] layer state not being remembered

Anthony Carnemolla tenchikan at gmail.com
Fri Dec 16 03:25:53 CET 2011


Hi all.

Sorry to intrude, but I had to join this list so that I could post this. I
don't really know how else to post a bug at this point...

I've been setting up a mapping app with a mappanel inside a container that
is added as an item in a card layout that is added as an item in a border
layout.

In this configuration, I've got the state being saved using the ext cookie
provider. This works fine with the map center and zoom properties, but it
doesn't work with layer visibility (specifically, I needed my base layer
choice to be remembered).

After many hours of hunting and chasing variables, figuring that I just
didn't configure things correctly, I dug into the geoext code. In
mappanel.js, the renderMap function doesn't get called in the afterRender
event as I expected. If the map panel is contained in some other container
(as mine is), it doesn't get rendered until that outer container is done
with its layout. I suppose this is so that the map's dimensions can fit in
appropriately and whatnot.
But, if the map is not yet renderred, then the layers are not yet bound to
the map, and any attempt to restore their state using the map panel state
restoration functions will fail.

This problem still exists in the copy of geoext 1.1 rc1 that I just
downloaded.

My hack to fix it for myself was to overwrite these three items in the
creation of my map panel object:

stateEvents: ["aftermapmove",
                "changebaselayer", // want to listen to this event, too
              "afterlayervisibilitychange",
              "afterlayeropacitychange"],

renderMap: function() {
    var map = this.map;
    map.render(this.body.dom);

    this.layers.bind(map);

    if(map.layers.length > 0) {
        if(this.center || this.zoom != null) {
            // both do not have to be defined
            map.setCenter(this.center, this.zoom);
        } else if(this.extent) {
            map.zoomToExtent(this.extent);
        } else {
            map.zoomToMaxExtent();
        }
    }

    // apply the state again, now that the map REALLY is rendered
    this.applyState(this.state);
},

applyState: function(state) {

    // if we get strings for state.x, state.y or state.zoom
    // OpenLayers will take care of converting them to the
    // appropriate types so we don't bother with that
    this.center = new OpenLayers.LonLat(state.x, state.y);
    this.zoom = state.zoom;

    // set layer visibility and opacity
    var i, l, layer, layerId, visibility, opacity;
    var layers = this.map.layers;
    for(i=0, l=layers.length; i<l; i++) {
        layer = layers[i];
        layerId = this.prettyStateKeys ? layer.name : layer.id;
        visibility = state["visibility_" + layerId];
        if(visibility !== undefined) {
            // convert to boolean
            visibility = (/^true$/i).test(visibility);
            if(layer.isBaseLayer) {
                if(visibility) {
                    this.map.setBaseLayer(layer);
                }
            } else {
                layer.setVisibility(visibility);
            }
        }
        opacity = state["opacity_" + layerId];
        if(opacity !== undefined) {
            layer.setOpacity(opacity);
        }
    }

    // store the state in the mappanel object so I can call it the second
time
    // for my stupid hack
    this["state"] = state;
},

I don't know enough about extending objects in js to do better than that.
Also, note that the code I'm reusing is from geoext 1.0.

If this has already been addressed and fixed, I apologize.

-- 
γνῶθι σεαυτόν
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.geoext.org/pipermail/users/attachments/20111215/ea55e2d7/attachment.htm 


More information about the Users mailing list