2

I've been playing around with extending controls in OpenLayers 3. I've built a control which grabs a legend image from a mapserver with a GetLegendGraphics request. However, when I add the control to the map, the map object doesn't get passed to the control. I think the inheritance works just fine, because the control does have a getMap() function, but it returns undefined. Does anyone have an idea what am I doing wrong?

Code:

var ol3_legend = function(e) {
    var options = e || {};
    var wmsVersion = options.wmsVersion || '1.3.0';
    var format = options.format || 'image/png';
    var legendP = document.createElement('p');
    legendP.innerHTML = 'Legend:';
    var legendDiv = document.createElement('div');
    legendDiv.className = options.class + ' ol-unselectable';
    legendDiv.appendChild(legendP);
    var layers = this.getMap().getLayers().getArray();
    for (var i=0;i<layers.length;i++) {
        if (layers[i].get('showLegend') === true) {
            try {
                var url = layers[i].getSource().getUrls()[0];
            }
            catch(err) {
                var url = layers[i].getSource().getUrl();
            }
            var legendImg = document.createElement('img');
            legendImg.src = url + '&version=' + wmsVersion + '&service=WMS&request=GetLegendGraphic&sld_version=1.1.0&layer=' + layers[i].getSource().getParams().layers + '&format=' + format;
            legendDiv.appendChild(legendImg);
        }
    }
    ol.control.Control.call(this, {
        element: legendDiv
    });
}
ol.inherits(ol3_legend, ol.control.Control);

ol3_map.addControl(new ol3_legend({
    class: 'ol_legend'
}));

Output:

Uncaught TypeError: Cannot read property 'getLayers' of undefined

Workaround (just the modified lines):

var layers = options.map.getLayers().getArray();

ol3_map.addControl(new ol3_legend({
    map: ol3_map,
    class: 'ol_legend'
}));

The problem is, that I have to provide the map object, which makes restrictions if I would like to reuse the code later.

Working fiddle.

3

The problem is that you are using getMap() in the constructor of your control. But at the moment you instantiate the control, it is not yet added to the map. So, getMap() returns undefined.

You can overwrite setMap(map) in your control which is called by the map when executing map.setControl().

ol3_legend.prototype.setMap = function(map) {
  ol.control.Control.prototype.setMap.call(this, map);
  console.log(map);
};
  • The problem with this method is, that if I overwrite the setMap function, I have to rebuild the library with closure. I would prefer a solution which can be written as a module. So far I have divided the control, so the map-dependent part is in a separate, draw function, but it has to be called after adding the control to the map. Aren't there any simpler solution, like in OpenLayers 2? – Gabor Farkas Feb 26 '15 at 10:17
  • I updated my answer with an example. You don't need to compile ol to overwrite setMap. – tsauerwein Feb 26 '15 at 10:33
  • Wow, I just missed the second line. Easy. Thank you very much. – Gabor Farkas Feb 26 '15 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.