Create an OpenLayers map programmatically

Sometimes it is useful to abstract away the repetitive layer creation code with a configuration-based approach.

For example consider this very simple map taken from the OpenLayers examples:

var road = new OpenLayers.Layer.Bing({
name: "Road",
key: apiKey,
type: "Road"
});
var hybrid = new OpenLayers.Layer.Bing({
name: "Hybrid",
key: apiKey,
type: "AerialWithLabels"
});
var aerial = new OpenLayers.Layer.Bing({
name: "Aerial",
key: apiKey,
type: "Aerial"
});
map.addLayers([road, hybrid, aerial]);
view raw bing.js hosted with ❤ by GitHub
How could we avoid repeating invoking the layer contructor and instead provde a framework that allows us to instantiate any layer with just configuration? The solution is quite simple.

First of all we need to define our configuration structure, which is straightforward to do in javascript:

var layers=[
{provider:'OpenLayers.Layer.Bing',args:[{name: "Road",key: "AqTGBsziZHIJYYxgivLBf0hVdrAk9mWO5cQcb8Yux8sW5M8c8opEC2lZqKR1ZZXf",type: "Road"}]},
{provider:'OpenLayers.Layer.Bing',args:[{name: "Hybrid",key: "AqTGBsziZHIJYYxgivLBf0hVdrAk9mWO5cQcb8Yux8sW5M8c8opEC2lZqKR1ZZXf",type: "AerialWithLabels"}]},
{provider:'OpenLayers.Layer.Bing',args:[{name: "Aerial",key: "AqTGBsziZHIJYYxgivLBf0hVdrAk9mWO5cQcb8Yux8sW5M8c8opEC2lZqKR1ZZXf",type: "Aerial"}]}
];
view raw cfg_based.js hosted with ❤ by GitHub
Note that the constructor, which we call provider, has not yet been dereferenced to the actual function. This is on purpose because in this way we can load the configuration independently of OpenLayers. This can be useful especially when trying to optimize page loading time.

Now all we need is some basic glue to make it all work. Basically a builder function and the a for loop over the configuration array.

function assembleLayer(conf) {
var constructorr=window, path=conf.provider.split(".");
// get a reference to the constructor, by walking the provider path
for(var i=0,l=path.length;i<l;i++) { constructorr=constructorr[path[i]]; }
// following constructor code from: http://stackoverflow.com/a/1608546/887883
// now invoke it
function F() {
return constructorr.apply(this, conf.args);
}
F.prototype = constructorr.prototype;
return new F();
}
for(var i=0,l=layers.length;i<l;i++) {
map.addLayer(assembleLayer(layers[i]));
}
view raw map.js hosted with ❤ by GitHub

Popular posts

Mirth: recover space when mirthdb grows out of control

1/4/2000 to 1/4/2025: the beginning

From 0 to ZFS replication in 5m with syncoid