Index: src/django_gheat/wlheatmap/templates/home.html
===================================================================
--- src/django_gheat/wlheatmap/templates/home.html	(revision 9407)
+++ src/django_gheat/wlheatmap/templates/home.html	(revision 9544)
@@ -5,5 +5,5 @@
   <script type="text/javascript" language="Javascript" src="{{ STATIC_URL }}jquery-1.6.2.min.js"></script>
   <script type="text/javascript" language="Javascript" src="{{ STATIC_URL }}OpenLayers.js"></script>
-  <script type="text/javascript" language="Javascript" src="{{ STATIC_URL }}OpenStreetMap.js"></script> 
+  <script type="text/javascript" language="Javascript" src="{% url wlheatmap.js_layer_base %}"></script> 
   <script type="text/javascript" language="Javascript" src="{{ STATIC_URL }}heatmap.js"></script>
   <script type="text/javascript" language="javascript" src="{{ STATIC_URL }}jquery.chained.js"></script>
Index: src/django_gheat/wlheatmap/templates/js/LayerBase.js
===================================================================
--- src/django_gheat/wlheatmap/templates/js/LayerBase.js	(revision 9544)
+++ src/django_gheat/wlheatmap/templates/js/LayerBase.js	(revision 9544)
@@ -0,0 +1,205 @@
+/**
+ * Namespace: Util.OSM
+ */
+OpenLayers.Util.OSM = {};
+
+/**
+ * Constant: MISSING_TILE_URL
+ * {String} URL of image to display for missing tiles
+ */
+OpenLayers.Util.OSM.MISSING_TILE_URL = "http://openstreetmap.org/openlayers/img/404.png";
+
+/**
+ * Property: originalOnImageLoadError
+ * {Function} Original onImageLoadError function.
+ */
+OpenLayers.Util.OSM.originalOnImageLoadError = OpenLayers.Util.onImageLoadError;
+
+/**
+ * Function: onImageLoadError
+ */
+OpenLayers.Util.onImageLoadError = function() {
+    if (this.src.match(/^http:\/\/[abc]\.[a-z]+\.openstreetmap\.org\//)) {
+        this.src = OpenLayers.Util.OSM.MISSING_TILE_URL;
+    } else if (this.src.match(/^http:\/\/[def]\.tah\.openstreetmap\.org\//)) {
+        // do nothing - this layer is transparent
+    } else {
+        OpenLayers.Util.OSM.originalOnImageLoadError;
+    }
+};
+
+function get_balanced_urls(prefix, balancers, suffix) {
+  var urls = [];
+  for (var i=0; i < balancers.length; i++) {
+    urls.push(prefix + balancers[i] + suffix);
+  };
+  return urls;
+};
+
+
+
+/**
+ * Class: OpenLayers.Layer.OSM.Mapnik
+ *
+ * Inherits from:
+ *  - <OpenLayers.Layer.OSM>
+ */
+OpenLayers.Layer.OSM.Mapnik = OpenLayers.Class(OpenLayers.Layer.OSM, {
+    /**
+     * Constructor: OpenLayers.Layer.OSM.Mapnik
+     *
+     * Parameters:
+     * name - {String}
+     * options - {Object} Hashtable of extra options to tag onto the layer
+     */
+    initialize: function(name, options) {
+        var url = get_balanced_urls('http://', {{ settings.OSM_PROXY_CDN_DOMAINS|safe }}, '{{ settings.DJANGO_PREFIX }}/osm-proxy/${z}/${x},${y}.png');
+        options = OpenLayers.Util.extend({ numZoomLevels: 19 }, options);
+        var newArguments = [name, url, options];
+        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
+    },
+
+    CLASS_NAME: "OpenLayers.Layer.OSM.Mapnik"
+});
+
+/**
+ * Class: OpenLayers.Layer.OSM.Osmarender
+ *
+ * Inherits from:
+ *  - <OpenLayers.Layer.OSM>
+ */
+OpenLayers.Layer.OSM.Osmarender = OpenLayers.Class(OpenLayers.Layer.OSM, {
+    /**
+     * Constructor: OpenLayers.Layer.OSM.Osmarender
+     *
+     * Parameters:
+     * name - {String}
+     * options - {Object} Hashtable of extra options to tag onto the layer
+     */
+    initialize: function(name, options) {
+        var url = [
+            "http://a.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
+            "http://b.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
+            "http://c.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"
+        ];
+        options = OpenLayers.Util.extend({ numZoomLevels: 18 }, options);
+        var newArguments = [name, url, options];
+        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
+    },
+
+    CLASS_NAME: "OpenLayers.Layer.OSM.Osmarender"
+});
+
+/**
+ * Class: OpenLayers.Layer.OSM.CycleMap
+ *
+ * Inherits from:
+ *  - <OpenLayers.Layer.OSM>
+ */
+OpenLayers.Layer.OSM.CycleMap = OpenLayers.Class(OpenLayers.Layer.OSM, {
+    /**
+     * Constructor: OpenLayers.Layer.OSM.CycleMap
+     *
+     * Parameters:
+     * name - {String}
+     * options - {Object} Hashtable of extra options to tag onto the layer
+     */
+    initialize: function(name, options) {
+        var url = [
+            "http://a.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png",
+            "http://b.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png",
+            "http://c.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png"
+        ];
+        options = OpenLayers.Util.extend({ numZoomLevels: 19 }, options);
+        var newArguments = [name, url, options];
+        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
+    },
+
+    CLASS_NAME: "OpenLayers.Layer.OSM.CycleMap"
+});
+
+/**
+ * Class: OpenLayers.Layer.OSM.Maplint
+ *
+ * Inherits from:
+ *  - <OpenLayers.Layer.OSM>
+ */
+OpenLayers.Layer.OSM.Maplint = OpenLayers.Class(OpenLayers.Layer.OSM, {
+    /**
+     * Constructor: OpenLayers.Layer.OSM.Maplint
+     *
+     * Parameters:
+     * name - {String}
+     * options - {Object} Hashtable of extra options to tag onto the layer
+     */
+    initialize: function(name, options) {
+        var url = [
+            "http://d.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png",
+            "http://e.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png",
+            "http://f.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png"
+        ];
+        options = OpenLayers.Util.extend({ numZoomLevels: 21, isBaseLayer: false, visibility: false }, options);
+        var newArguments = [name, url, options];
+        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
+    },
+
+    CLASS_NAME: "OpenLayers.Layer.OSM.Maplint"
+});
+
+/**
+ * Gheat layer 
+ */
+OpenLayers.Layer.OSM.Overlay1 = OpenLayers.Class(OpenLayers.Layer.OSM, {
+    initialize: function(name, options) {
+        var url = [
+            "/gheat/classic/${z}/${x},${y}.png"
+        ];
+        options = OpenLayers.Util.extend({ numZoomLevels: 21 }, options);
+        var newArguments = [name, url, options];
+        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
+    },
+    colour: "0,0,0",
+    CLASS_NAME: "OpenLayers.Layer.Overlay"
+});
+
+/**
+ * All accespoints 
+ */
+OpenLayers.Layer.OSM.Overlay2 = OpenLayers.Class(OpenLayers.Layer.OSM, {
+    initialize: function(name, options) {
+        var url = get_balanced_urls('http://', {{ settings.DJANGO_CDN_DOMAINS|safe }}, '{{ settings.DJANGO_PREFIX }}/wlheatmap/tile/${z}/${x},${y}.png?colour=90,90,90');
+        options = OpenLayers.Util.extend({ numZoomLevels: 21 }, options);
+        var newArguments = [name, url, options];
+        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
+    },
+    colour: "90,90,90",
+    CLASS_NAME: "OpenLayers.Layer.Overlay"
+});
+
+/**
+ * Wireless Leiden nodes
+ */
+OpenLayers.Layer.OSM.Overlay3 = OpenLayers.Class(OpenLayers.Layer.OSM, {
+    initialize: function(name, options) {
+        var url = get_balanced_urls('http://', {{ settings.DJANGO_CDN_DOMAINS|safe }}, '{{ settings.DJANGO_PREFIX }}/wlheatmap/tile/${z}/${x},${y}.png?colour=255,0,0&accespoint__ssid__icontains=WirelessLeiden');
+        options = OpenLayers.Util.extend({ numZoomLevels: 21 }, options);
+        var newArguments = [name, url, options];
+        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
+    },
+    colour: "255,0,0",
+    CLASS_NAME: "OpenLayers.Layer.Overlay"
+});
+
+/**
+ * Signal strength 
+ */
+OpenLayers.Layer.OSM.Overlay4 = OpenLayers.Class(OpenLayers.Layer.OSM, {
+  initialize: function(name, options) {
+    var url = get_balanced_urls('http://', {{ settings.DJANGO_CDN_DOMAINS|safe }}, '{{ settings.DJANGO_PREFIX }}/wlheatmap/tile/${z}/${x},${y}.png?colour=50,150,50&signaal__gte=0&signaal__lte=100');
+    options = OpenLayers.Util.extend({ numZoomLevels: 21 }, options);
+    var newArguments = [name, url, options];
+    OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
+  },
+  colour: "50,150,50",
+  CLASS_NAME: "OpenLayers.Layer.Overlay"
+});
