Skip to content

Instantly share code, notes, and snippets.

@tmcw
Created March 23, 2012 20:39
Show Gist options
  • Save tmcw/2174728 to your computer and use it in GitHub Desktop.
Save tmcw/2174728 to your computer and use it in GitHub Desktop.
Basey = OpenLayers.Class(OpenLayers.Control, {
layerStates: null,
layersDiv: null,
ascending: true,
initialize: function(options) {
OpenLayers.Control.prototype.initialize.apply(this, arguments);
this.layerStates = [];
},
destroy: function() {
OpenLayers.Event.stopObservingElement(this.div);
//clear out layers info and unregister their events
this.clearLayersArray("base");
this.clearLayersArray("data");
this.map.events.un({
"addlayer": this.redraw,
"changelayer": this.redraw,
"removelayer": this.redraw,
"changebaselayer": this.redraw,
scope: this
});
OpenLayers.Control.prototype.destroy.apply(this, arguments);
},
setMap: function(map) {
OpenLayers.Control.prototype.setMap.apply(this, arguments);
this.map.events.on({
"addlayer": this.redraw,
"changelayer": this.redraw,
"removelayer": this.redraw,
"changebaselayer": this.redraw,
scope: this
});
},
draw: function() {
OpenLayers.Control.prototype.draw.apply(this);
this.loadContents();
this.redraw();
return this.div;
},
checkRedraw: function() {
var redraw = false;
if ( !this.layerStates.length ||
(this.map.layers.length != this.layerStates.length) ) {
redraw = true;
} else {
for (var i=0, len=this.layerStates.length; i<len; i++) {
var layerState = this.layerStates[i];
var layer = this.map.layers[i];
if ( (layerState.name != layer.name) ||
(layerState.inRange != layer.inRange) ||
(layerState.id != layer.id) ||
(layerState.visibility != layer.visibility) ) {
redraw = true;
break;
}
}
}
return redraw;
},
redraw: function() {
if (!this.checkRedraw()) {
return this.div;
}
this.div.innerHTML = '';
var len = this.map.layers.length;
this.layerStates = [];
for (var i = 0; i < this.map.layers.length; i++) {
var layer = this.map.layers[i];
this.layerStates[i] = {
'name': layer.name,
'visibility': layer.visibility,
'inRange': layer.inRange,
'id': layer.id
};
}
var layers = this.map.layers.slice();
if (!this.ascending) { layers.reverse(); }
for (var i = 0, len = layers.length; i < len; i++) {
var layer = layers[i];
var baseLayer = layer.isBaseLayer;
if (layer.displayInLayerSwitcher) {
var on = (baseLayer) ? (layer == this.map.baseLayer)
: layer.getVisibility();
var layerElem = document.createElement('a');
layerElem.id = this.id + '_input_' + layer.name;
layerElem.name = (baseLayer) ? this.id + '_baseLayers' : layer.name;
layerElem.innerHTML = layer.name;
layerElem.href = '#';
layerElem.value = layer.name;
OpenLayers.Element.addClass(layerElem, 'basey');
OpenLayers.Element.addClass(layerElem,
'basey-' + (baseLayer ? 'base' : 'over'));
OpenLayers.Element.addClass(layerElem,
'basey-' + (on ? 'on' : 'off'));
if (!baseLayer && !layer.inRange) {
layerElem.disabled = true;
}
var context = {
'layerElem': layerElem,
'layer': layer,
'layerSwitcher': this
};
OpenLayers.Event.observe(layerElem, 'mouseup',
OpenLayers.Function.bindAsEventListener(
this.onInputClick,
context)
);
this.div.appendChild(layerElem);
}
}
return this.div;
},
onInputClick: function(e) {
this.layer.map.setBaseLayer(this.layer);
OpenLayers.Event.stop(e);
},
onLayerClick: function(e) {
this.updateMap();
},
updateMap: function() {
// set the newly selected base layer
for(var i=0, len=this.baseLayers.length; i<len; i++) {
var layerEntry = this.baseLayers[i];
if (layerEntry.inputElem.checked) {
this.map.setBaseLayer(layerEntry.layer, false);
}
}
// set the correct visibilities for the overlays
for(var i=0, len=this.dataLayers.length; i<len; i++) {
var layerEntry = this.dataLayers[i];
layerEntry.layer.setVisibility(layerEntry.inputElem.checked);
}
},
loadContents: function() {
//configure main div
OpenLayers.Event.observe(this.div, 'mouseup',
OpenLayers.Function.bindAsEventListener(this.mouseUp, this));
OpenLayers.Event.observe(this.div, 'click',
this.ignoreEvent);
OpenLayers.Event.observe(this.div, 'mousedown',
OpenLayers.Function.bindAsEventListener(this.mouseDown, this));
OpenLayers.Event.observe(this.div, 'dblclick', this.ignoreEvent);
this.dataLayersDiv = document.createElement('div');
OpenLayers.Element.addClass(this.dataLayersDiv, 'dataLayersDiv');
// this.div.appendChild(this.layersDiv);
},
ignoreEvent: function(evt) {
OpenLayers.Event.stop(evt);
},
mouseDown: function(evt) {
this.isMouseDown = true;
this.ignoreEvent(evt);
},
mouseUp: function(evt) {
if (this.isMouseDown) {
this.isMouseDown = false;
this.ignoreEvent(evt);
}
},
CLASS_NAME: "Basey"
});
<!DOCTYPE html>
<html>
<head>
<title>OpenLayers Basey</title>
<script type='text/javascript' src='http://openlayers.org/api/OpenLayers.js'></script>
<script type='text/javascript' src='basey.js'></script>
<script type='text/javascript'>
window.onload = function() {
map = new OpenLayers.Map('map', {
controls: [
new OpenLayers.Control.ArgParser(),
new OpenLayers.Control.Attribution(),
new Basey(),
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.ScaleLine({geodesic: true})
],
units: "m",
maxResolution: 156543.0339,
numZoomLevels: 20,
displayProjection: new OpenLayers.Projection("EPSG:4326")
});
var mapnik = new OpenLayers.Layer.XYZ('Standard',
"http://tile.openstreetmap.org/${z}/${x}/${y}.png", {
attribution: "",
keyid: "mapnik",
sphericalMercator: true,
displayOutsideMaxExtent: true,
wrapDateLine: true,
layerCode: "M"
});
map.addLayer(mapnik);
var cycle = new OpenLayers.Layer.XYZ('Cycle Map',
"http://a.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png", {
attribution: "",
keyid: "mapnik",
sphericalMercator: true,
displayOutsideMaxExtent: true,
wrapDateLine: true,
layerCode: "M"
});
map.addLayer(cycle);
var transport = new OpenLayers.Layer.XYZ('Transport Map',
"http://a.tile2.opencyclemap.org/transport/${z}/${x}/${y}.png", {
attribution: "",
keyid: "mapnik",
sphericalMercator: true,
displayOutsideMaxExtent: true,
wrapDateLine: true,
layerCode: "M"
});
map.addLayer(transport);
var mapquest = new OpenLayers.Layer.XYZ('MapQuest Open', [
"http://otile1.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile2.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile4.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png"
], {
attribution: "Tiles courtesy of <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a> <img src='http://developer.mapquest.com/content/osm/mq_logo.png'>",
keyid: "mapquest",
sphericalMercator: true,
displayOutsideMaxExtent: true,
wrapDateLine: true,
numZoomLevels: 19,
layerCode: "Q"
});
map.addLayer(mapquest);
map.zoomTo(5);
return map;
}
</script>
<style type='text/css'>
body {
font: 13px/20px 'Helvetica Neue';
}
.Basey {
position:absolute;
top:10px;
right:10px;
background:#fff;
border:1px solid #eee;
border-radius:5px;
padding-left:15px;
min-width:150px;
background: #fff url('arrow.png') no-repeat;
background-position:5px 5px;
}
.Basey a.basey {
display:block;
text-decoration:none;
color:#838383;
padding:2px 5px;
}
.Basey a.basey-on {
color:#000;
}
.Basey a.basey-off {
display:none;
}
.Basey:hover a {
border-top:1px solid #eee;
}
.Basey:hover a:first-child {
border-top:none;
}
.Basey:hover a.basey-off {
display:block;
}
</style>
</head>
<body>
<div id='map' style='width:600px;height:600px;'></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment