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.
Best Answer
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 executingmap.setControl()
.