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:
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:
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.
For example consider this very simple map taken from the OpenLayers examples:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]); |
First of all we need to define our configuration structure, which is straightforward to do in javascript:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"}]} | |
]; |
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for(var i=0,l=layers.length;i<l;i++) { | |
map.addLayer(assembleLayer(layers[i])); | |
} |