Index: src/django_gheat/gheat/__init__.py
===================================================================
--- src/django_gheat/gheat/__init__.py	(revision 9823)
+++ src/django_gheat/gheat/__init__.py	(revision 10615)
@@ -1,111 +1,0 @@
-import logging
-import os
-
-from gheat import gheatsettings as settings
-
-from django.core.exceptions import ImproperlyConfigured
-from django.db import connection
-
-# Logging config
-# ==============
-
-if settings.DEBUG:
-    level = logging.WARNING
-else:
-    level = logging.WARNING
-if os.getenv('DEBUG', None):
-    level = logging.DEBUG
-
-logging.basicConfig(level=level) # Ack! This should be in Aspen. :^(
-log = logging.getLogger('gheat')
-
-
-# Configuration
-# =============
-# Set some things that backends will need.
-ALWAYS_BUILD = settings.GHEAT_ALWAYS_BUILD = False
-BUILD_EMPTIES = settings.GHEAT_BUILD_EMPTIES = False
-
-DIRMODE = settings.GHEAT_DIRMODE
-try:
-    DIRMODE = int(eval(DIRMODE))
-except (NameError, SyntaxError, ValueError):
-    raise ImproperlyConfigured("dirmode (%s) must be an integer." % dirmode)
-
-SIZE = 256 # size of (square) tile; NB: changing this will break gmerc calls!
-MAX_ZOOM = 22 # this depends on Google API; 0 is furthest out as of recent ver.
-
-
-# Try to find an image library.
-# =============================
-
-BACKEND = None 
-BACKEND_PIL = False 
-BACKEND_PYGAME = False
-
-_want = settings.GHEAT_BACKEND.lower()
-if _want not in ('pil', 'pygame', ''):
-    raise ImproperlyConfigured( "The %s backend is not supported, only PIL and "
-                            + "Pygame (assuming those libraries are installed)."
-                             )
-
-if _want:
-    if _want == 'pygame':
-        from gheat import pygame_ as backend
-    elif _want == 'pil':
-        from gheat import pil_ as backend
-    BACKEND = _want
-else:
-    try:
-        from gheat import pygame_ as backend
-        BACKEND = 'pygame'
-    except ImportError:
-        try:
-            from gheat import pil_ as backend
-            BACKEND = 'pil'
-        except ImportError:
-            raise
-            pass
-    
-    if BACKEND is None:
-        raise ImportError("Neither Pygame nor PIL could be imported.")
-
-BACKEND_PYGAME = BACKEND == 'pygame'
-BACKEND_PIL = BACKEND == 'pil'
-
-log.info("Using the %s library" % BACKEND)
-
-
-# Set up color schemes and dots.
-# ==============================
-
-color_schemes = dict()          # this is used below
-    
-_color_schemes_dir = os.path.join(settings.GHEAT_CONF_DIR, 'color-schemes')
-for fname in os.listdir(_color_schemes_dir):
-    if not fname.endswith('.png'):
-        continue
-    name = os.path.splitext(fname)[0]
-    fspath = os.path.join(_color_schemes_dir, fname)
-    color_schemes[name] = backend.ColorScheme(name, fspath)
-
-def load_dots(backend):
-    """Given a backend module, return a mapping of zoom level to Dot object.
-    """
-    return dict([(zoom, backend.Dot(zoom)) for zoom in range(MAX_ZOOM)])
-dots = load_dots(backend) # factored for easier use from scripts
-
-# Some util methods
-# =================
-def translate(root, url):
-    """Translate a URL to the filesystem.
-
-    We specifically avoid removing symlinks in the path so that the filepath
-    remains under the website root. Also, we don't want trailing slashes for
-    directories.
-
-    """
-    parts = [root] + url.lstrip('/').split('/')
-    return os.sep.join(parts).rstrip(os.sep)
-
-ROOT = settings.GHEAT_MEDIA_ROOT
Index: src/django_gheat/gheat/base.py
===================================================================
--- src/django_gheat/gheat/base.py	(revision 9823)
+++ 	(revision )
@@ -1,256 +1,0 @@
-import datetime
-import os
-import stat
-
-from django.core.exceptions import ImproperlyConfigured
-
-import gheat
-import gheat.opacity
-from gheat.models import Accesspoint, Gebruiker, Meting
-from gheat import gheatsettings as settings
-from gheat import gmerc
-from gheat import BUILD_EMPTIES, DIRMODE, SIZE, log
-
-
-class ColorScheme(object):
-    """Base class for color scheme representations.
-    """
-
-    def __init__(self, name, fspath):
-        """Takes the name and filesystem path of the defining PNG.
-        """
-#        if aspen.mode.DEVDEB:
-#            aspen.restarter.track(fspath)
-        self.hook_set(fspath)
-        self.empties_dir = os.path.join(settings.GHEAT_MEDIA_ROOT, name, 'empties')
-        self.build_empties()
-
-
-    def build_empties(self):
-        """Build empty tiles for this color scheme.
-        """
-        empties_dir = self.empties_dir
-
-        if not BUILD_EMPTIES:
-            log.info("not building empty tiles for %s " % self)
-        else:    
-            if not os.path.isdir(empties_dir):
-                os.makedirs(empties_dir, DIRMODE)
-            if not os.access(empties_dir, os.R_OK|os.W_OK|os.X_OK):
-                raise ImproperlyConfigured( "Permissions too restrictive on "
-                                        + "empties directory "
-                                        + "(%s)." % empties_dir
-                                         )
-            for fname in os.listdir(empties_dir):
-                if fname.endswith('.png'):
-                    os.remove(os.path.join(empties_dir, fname))
-            for zoom, opacity in gheat.opacity.zoom_to_opacity.items():
-                fspath = os.path.join(empties_dir, str(zoom)+'.png')
-                self.hook_build_empty(opacity, fspath)
-            
-            log.info("building empty tiles in %s" % empties_dir)
-
-
-    def get_empty_fspath(self, zoom):
-        fspath = os.path.join(self.empties_dir, str(zoom)+'.png')
-        if not os.path.isfile(fspath):
-            self.build_empties() # so we can rebuild empties on the fly
-        return fspath
-
-
-    def hook_set(self):
-        """Set things that your backend will want later.
-        """
-        raise NotImplementedError
-
-
-    def hook_build_empty(self, opacity, fspath):
-        """Given an opacity and a path, save an empty tile.
-        """
-        raise NotImplementedError
-
-
-class Dot(object):
-    """Base class for dot representations.
-
-    Unlike color scheme, the same basic external API works for both backends. 
-    How we compute that API is different, though.
-
-    """
-
-    def __init__(self, zoom):
-        """Takes a zoom level.
-        """
-        name = 'dot%d.png' % zoom
-        fspath = os.path.join(settings.GHEAT_CONF_DIR, 'dots', name)
-        self.img, self.half_size = self.hook_get(fspath)
-        
-    def hook_get(self, fspath):
-        """Given a filesystem path, return two items.
-        """
-        raise NotImplementedError
-
-
-class Tile(object):
-    """Base class for tile representations.
-    """
-
-    img = None
-
-    def __init__(self, color_scheme, dots, zoom, x, y, fspath):
-        """x and y are tile coords per Google Maps.
-        """
-
-        # Calculate some things.
-        # ======================
-
-        dot = dots[zoom]
-
-
-        # Translate tile to pixel coords.
-        # -------------------------------
-
-        x1 = x * SIZE
-        x2 = x1 + 255
-        y1 = y * SIZE
-        y2 = y1 + 255
-    
-    
-        # Expand bounds by one-half dot width.
-        # ------------------------------------
-    
-        x1 = x1 - dot.half_size
-        x2 = x2 + dot.half_size
-        y1 = y1 - dot.half_size
-        y2 = y2 + dot.half_size
-        expanded_size = (x2-x1, y2-y1)
-    
-    
-        # Translate new pixel bounds to lat/lng.
-        # --------------------------------------
-    
-        n, w = gmerc.px2ll(x1, y1, zoom)
-        s, e = gmerc.px2ll(x2, y2, zoom)
-
-
-        # Save
-        # ====
-
-        self.dot = dot.img
-        self.pad = dot.half_size
-
-        self.x = x
-        self.y = y
-
-        self.x1 = x1
-        self.y1 = y1
-
-        self.x2 = x2
-        self.y2 = y2
-
-        self.expanded_size = expanded_size
-        self.llbound = (n,s,e,w)
-        self.zoom = zoom
-        self.fspath = fspath
-        self.opacity = gheat.opacity.zoom_to_opacity[zoom]
-        self.color_scheme = color_scheme
-  
-
-    def is_empty(self):
-        """With attributes set on self, return a boolean.
-
-        Calc lat/lng bounds of this tile (include half-dot-width of padding)
-        SELECT count(uid) FROM points
-        """
-        numpoints = Meting.objects.num_points(self)
-        return numpoints == 0
-
-
-    def is_stale(self):
-        """With attributes set on self, return a boolean.
-
-        Calc lat/lng bounds of this tile (include half-dot-width of padding)
-        SELECT count(uid) FROM points WHERE modtime < modtime_tile
-        """
-        if not os.path.isfile(self.fspath):
-            return True
-   
-        timestamp = os.stat(self.fspath)[stat.ST_MTIME]
-        datum = datetime.datetime.fromtimestamp(timestamp)
-
-        numpoints = Meting.objects.num_points(self, datum)
-
-        return numpoints > 0
-
-
-    def rebuild(self):
-        """Rebuild the image at self.img. Real work delegated to subclasses.
-        """
-
-        # Calculate points.
-        # =================
-        # Build a closure that gives us the x,y pixel coords of the points
-        # to be included on this tile, relative to the top-left of the tile.
-
-        _points = Meting.objects.points_inside(self)
-   
-        def points():
-            """Yield x,y pixel coords within this tile, top-left of dot.
-            """
-            result = []
-            for point in _points:
-                x, y = gmerc.ll2px(point.latitude, point.longitude, self.zoom)
-                x = x - self.x1 # account for tile offset relative to
-                y = y - self.y1 #  overall map
-                point_signaal = point.signaal
-                while point_signaal > 0:
-                    result.append((x-self.pad,y-self.pad))
-                    point_signaal = point_signaal - 1
-            return result
-
-
-        # Main logic
-        # ==========
-        # Hand off to the subclass to actually build the image, then come back 
-        # here to maybe create a directory before handing back to the backend
-        # to actually write to disk.
-
-        self.img = self.hook_rebuild(points())
-
-        dirpath = os.path.dirname(self.fspath)
-        if dirpath and not os.path.isdir(dirpath):
-            os.makedirs(dirpath, DIRMODE)
-
-
-    def hook_rebuild(self, points, opacity):
-        """Rebuild and save the file using the current library.
-
-        The algorithm runs something like this:
-
-            o start a tile canvas/image that is a dots-worth oversized
-            o loop through points and multiply dots on the tile
-            o trim back down to straight tile size
-            o invert/colorize the image
-            o make it transparent
-
-        Return the img object; it will be sent back to hook_save after a
-        directory is made if needed.
-
-        Trim after looping because we multiply is the only step that needs the
-        extra information.
-
-        The coloring and inverting can happen in the same pixel manipulation 
-        because you can invert colors.png. That is a 1px by 256px PNG that maps
-        grayscale values to color values. You can customize that file to change
-        the coloration.
-
-        """
-        raise NotImplementedError
-
-
-    def save(self):
-        """Write the image at self.img to disk.
-        """
-        raise NotImplementedError
-
-
Index: src/django_gheat/gheat/gheatsettings.py
===================================================================
--- src/django_gheat/gheat/gheatsettings.py	(revision 9823)
+++ 	(revision )
@@ -1,20 +1,0 @@
-# Let the developer to override generic values for the gheat settings 
-# Normally set on a localsettings.py file or the same settings.py of your
-# home project
-from django.conf import settings
-
-from os.path import dirname, abspath, join
-# Default Gheat settings
-GHEAT_BACKEND = getattr(settings, 'GHEAT_BACKEND','PYGAME')
-GHEAT_ZOOM_OPAQUE=getattr(settings, 'GHEAT_ZOOM_OPAQUE', -1)
-GHEAT_ZOOM_TRANSPARENT=getattr(settings, 'GHEAT_ZOOM_TRANSPARENT', 17)
-GHEAT_FULL_OPAQUE=getattr(settings, 'GHEAT_FULL_OPAQUE', True)
-GHEAT_BUILD_EMPTIES=getattr(settings, 'GHEAT_BUILD_EMPTIES', True)
-GHEAT_ALWAYS_BUILD=getattr(settings, 'GHEAT_ALWAYS_BUILD', True)
-GHEAT_DIRMODE = getattr(settings, 'GHEAT_DIRMODE', '0755')
-
-GHEAT_CONF_DIR = getattr(settings, 'GHEAT_CONF_DIR', join(dirname(abspath(__file__)), 'etc'))
-GHEAT_MEDIA_ROOT = getattr(settings, 'GHEAT_MEDIA_ROOT', '/tmp/gheat/')
-DEBUG = settings.DEBUG
-
-
Index: src/django_gheat/gheat/gmerc.py
===================================================================
--- src/django_gheat/gheat/gmerc.py	(revision 9823)
+++ 	(revision )
@@ -1,121 +1,0 @@
-"""This is a port of Google's GMercatorProjection.fromLatLngToPixel.
-
-Doco on the original:
-
-  http://code.google.com/apis/maps/documentation/reference.html#GMercatorProjection
-
-
-Here's how I ported it:
-
-  http://blag.whit537.org/2007/07/how-to-hack-on-google-maps.html
-
-
-The goofy variable names below are an artifact of Google's javascript
-obfuscation.
-
-"""
-import math
-
-
-# Constants
-# =========
-# My knowledge of what these mean is undefined.
-
-CBK = [128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648, 4294967296, 8589934592, 17179869184, 34359738368, 68719476736, 137438953472]
-CEK = [0.7111111111111111, 1.4222222222222223, 2.8444444444444446, 5.688888888888889, 11.377777777777778, 22.755555555555556, 45.51111111111111, 91.02222222222223, 182.04444444444445, 364.0888888888889, 728.1777777777778, 1456.3555555555556, 2912.711111111111, 5825.422222222222, 11650.844444444445, 23301.68888888889, 46603.37777777778, 93206.75555555556, 186413.51111111112, 372827.02222222224, 745654.0444444445, 1491308.088888889, 2982616.177777778, 5965232.355555556, 11930464.711111112, 23860929.422222223, 47721858.844444446, 95443717.68888889, 190887435.37777779, 381774870.75555557, 763549741.5111111]
-CFK = [40.74366543152521, 81.48733086305042, 162.97466172610083, 325.94932345220167, 651.8986469044033, 1303.7972938088067, 2607.5945876176133, 5215.189175235227, 10430.378350470453, 20860.756700940907, 41721.51340188181, 83443.02680376363, 166886.05360752725, 333772.1072150545, 667544.214430109, 1335088.428860218, 2670176.857720436, 5340353.715440872, 10680707.430881744, 21361414.86176349, 42722829.72352698, 85445659.44705395, 170891318.8941079, 341782637.7882158, 683565275.5764316, 1367130551.1528633, 2734261102.3057265, 5468522204.611453, 10937044409.222906, 21874088818.445812, 43748177636.891624]
-
-
-def ll2px(lat, lng, zoom):
-    """Given two floats and an int, return a 2-tuple of ints.
-
-    Note that the pixel coordinates are tied to the entire map, not to the map
-    section currently in view.
-
-    """
-    assert isinstance(lat, (float, int, long)), \
-        ValueError("lat must be a float")
-    lat = float(lat)
-    assert isinstance(lng, (float, int, long)), \
-        ValueError("lng must be a float")
-    lng = float(lng)
-    assert isinstance(zoom, int), TypeError("zoom must be an int from 0 to 30")
-    assert 0 <= zoom <= 30, ValueError("zoom must be an int from 0 to 30")
-
-    cbk = CBK[zoom]
-
-    x = int(round(cbk + (lng * CEK[zoom])))
-
-    foo = math.sin(lat * math.pi / 180)
-    if foo < -0.9999:
-        foo = -0.9999
-    elif foo > 0.9999:
-        foo = 0.9999
-
-    y = int(round(cbk + (0.5 * math.log((1+foo)/(1-foo)) * (-CFK[zoom]))))
-
-    return (x, y)
-
-
-
-def px2ll(x, y, zoom):
-    """Given three ints, return a 2-tuple of floats.
-
-    Note that the pixel coordinates are tied to the entire map, not to the map
-    section currently in view.
-
-    """
-    assert isinstance(x, (int, long)), \
-        ValueError("px must be a 2-tuple of ints")
-    assert isinstance(y, (int, long)), \
-        ValueError("px must be a 2-tuple of ints")
-    assert isinstance(zoom, int), TypeError("zoom must be an int from 0 to 30")
-    assert 0 <= zoom <= 30, ValueError("zoom must be an int from 0 to 30")
-
-    foo = CBK[zoom]
-    lng = (x - foo) / CEK[zoom]
-    bar = (y - foo) / -CFK[zoom]
-    blam = 2 * math.atan(math.exp(bar)) - math.pi / 2
-    lat = blam / (math.pi / 180)
-
-    return (lat, lng)
-
-
-if __name__ == '__main__':
-
-    # Tests
-    # =====
-    # The un-round numbers were gotten by calling Google's js function.
-
-    data = [ (3, 39.81447, -98.565388, 463, 777)
-           , (3, 40.609538, -80.224528, 568, 771)
-
-           , (0, -90, 180, 256, 330)
-           , (0, -90, -180, 0, 330)
-           , (0, 90, 180, 256, -74)
-           , (0, 90, -180, 0, -74)
-
-           , (1, -90, 180, 512, 660)
-           , (1, -90, -180, 0, 660)
-           , (1, 90, 180, 512, -148)
-           , (1, 90, -180, 0, -148)
-
-           , (2, -90, 180, 1024, 1319)
-           , (2, -90, -180, 0, 1319)
-           , (2, 90, 180, 1024, -295)
-           , (2, 90, -180, 0, -295)
-
-            ]
-
-    def close(floats, floats2):
-        """Compare two sets of floats.
-        """
-        lat_actual = abs(floats[0] - floats2[0])
-        lng_actual = abs(floats[1] - floats2[1])
-        assert lat_actual < 1, (floats[0], floats2[0])
-        assert lng_actual < 1, (floats[1], floats2[1])
-        return True
-
-    for zoom, lat, lng, x, y in data:
-        assert ll2px(lat, lng, zoom) == (x, y), (lat, lng)
-        assert close(px2ll(x, y, zoom), (lat, lng)), (x, y)
Index: src/django_gheat/gheat/managers.py
===================================================================
--- src/django_gheat/gheat/managers.py	(revision 9823)
+++ 	(revision )
@@ -1,39 +1,0 @@
-# -*- coding: utf-8 -*-
-from django.db import models
-
-class MetingManager(models.Manager):
-
-    def actives(self):
-        return self.all()
-
-    def points_inside(self,tile):
-        '''
-            Search all the points inside the Tile
-        '''
-        lat1, lat2, lng1, lng2 = tile.llbound
-        qs = self.filter(
-            latitude__lte=lat1,
-            latitude__gte=lat2,
-            longitude__lte=lng1,
-            longitude__gte=lng2,
-            signaal__gt=0,
-            )
-        return qs
-
-    def num_points(self,tile,modtime=None):
-        '''
-            Count the number of points in a tile for a certain time
-        '''
-        qs = self.points_inside(tile)
-        if modtime:
-            qs.filter(modtime__gt=modtime)
-
-        return qs.count()
-
-
-    def clear_points(self):
-        '''
-            Clear all the points of the database
-        '''
-        self.actives().delete()
-
Index: src/django_gheat/gheat/opacity.py
===================================================================
--- src/django_gheat/gheat/opacity.py	(revision 9823)
+++ 	(revision )
@@ -1,63 +1,0 @@
-from django.core.exceptions import ImproperlyConfigured
-from django.conf import settings
-OPAQUE = 255
-TRANSPARENT = 0
-
-
-def _build_zoom_mapping(MAX_ZOOM=31):
-    """Build and return the zoom_to_opacity mapping
-    """
-    if MAX_ZOOM is None:
-        from gheat import MAX_ZOOM # won't use these in testing
-        from django.conf import settings
-
-    zoom_opaque = getattr(settings, 'GHEAT_ZOOM_OPAQUE', -15)
-
-    try:
-        zoom_opaque = int(zoom_opaque)
-    except ValueError:
-        raise ImproperlyConfigured("zoom_opaque must be an integer.")
-    
-    zoom_transparent = getattr(settings, 'GHEAT_ZOOM_TRANSPARENT', 15)
-    try:
-        zoom_transparent = int(zoom_transparent)
-    except ValueError:
-        raise ImproperlyConfigured("zoom_transparent must be an integer.")
-
-    num_opacity_steps = zoom_transparent - zoom_opaque
-    zoom_to_opacity = dict()
-    if num_opacity_steps < 1:               # don't want general fade
-        for zoom in range(0, MAX_ZOOM + 1):
-            zoom_to_opacity[zoom] = None
-    else:                                   # want general fade
-        opacity_step = OPAQUE / float(num_opacity_steps) # chunk of opacity
-        for zoom in range(0, MAX_ZOOM + 1):
-            if zoom <= zoom_opaque:
-                opacity = OPAQUE 
-            elif zoom >= zoom_transparent:
-                opacity = TRANSPARENT
-            else:
-                opacity = int(OPAQUE - ((zoom - zoom_opaque) * opacity_step))
-            zoom_to_opacity[zoom] = opacity
-
-    return zoom_to_opacity
-
-def _opaque_zoom_mapping(settings=None, MAX_ZOOM=31):
-    """Build and return the zoom_to_opacity mapping
-    """
-    if MAX_ZOOM is None:
-        from gheat import MAX_ZOOM # won't use these in testing
-        
-    zoom_to_opacity = dict()
-    for zoom in range(0, MAX_ZOOM + 1):
-        zoom_to_opacity[zoom] = OPAQUE
-
-    return zoom_to_opacity
-        
-full_opaque = getattr(settings, 'GHEAT_FULL_OPAQUE', True)
-
-if full_opaque:
-    zoom_to_opacity = _opaque_zoom_mapping()
-else:
-    zoom_to_opacity = _build_zoom_mapping()
-
Index: src/django_gheat/gheat/pil_.py
===================================================================
--- src/django_gheat/gheat/pil_.py	(revision 9823)
+++ 	(revision )
@@ -1,100 +1,0 @@
-import os
-
-from PIL import Image, ImageChops
-from gheat import SIZE, base
-from gheat.opacity import OPAQUE
-
-
-class ColorScheme(base.ColorScheme):
-
-    def hook_set(self, fspath):
-        self.colors = Image.open(fspath).load()
-
-    def hook_build_empty(self, opacity, fspath):
-        color = self.colors[0, 255]
-        if len(color) == 4: # color map has per-pixel alpha
-            (conf, pixel) = opacity, color[3] 
-            opacity = int(( (conf/255.0)    # from configuration
-                          * (pixel/255.0)   # from per-pixel alpha
-                           ) * 255)
-        color = color[:3] + (opacity,)
-        tile = Image.new('RGBA', (SIZE, SIZE), color)
-        tile.save(fspath, 'PNG')
-
-
-class Dot(base.Dot):
-    def hook_get(self, fspath):
-        img = Image.open(fspath)
-        half_size = img.size[0] / 2
-        return img, half_size 
-
-
-class Tile(base.Tile):
-    """Represent a tile; use the PIL backend.
-    """
-
-    def hook_rebuild(self, points):
-        """Given a list of points and an opacity, save a tile.
-    
-        This uses the PIL backend.
-    
-        """
-        tile = self._start()
-        tile = self._add_points(tile, points)
-        tile = self._trim(tile)
-        foo  = self._colorize(tile) # returns None
-        return tile
-
-
-    def _start(self):
-        return Image.new('RGBA', self.expanded_size, 'white')
-
-
-    def _add_points(self, tile, points):
-        for x,y in points:
-            dot_placed = Image.new('RGBA', self.expanded_size, 'white')
-            dot_placed.paste(self.dot, (x, y))
-            tile = ImageChops.multiply(tile, dot_placed)
-        return tile
-  
-
-    def _trim(self, tile):
-        tile = tile.crop((self.pad, self.pad, SIZE+self.pad, SIZE+self.pad))
-        tile = ImageChops.duplicate(tile) # converts ImageCrop => Image
-        return tile
-
-
-    def _colorize(self, tile):
-        _computed_opacities = dict()
-        pix = tile.load() # Image => PixelAccess
-        for x in range(SIZE):
-            for y in range(SIZE):
-
-                # Get color for this intensity
-                # ============================
-                # is a value 
-                
-                val = self.color_scheme.colors[0, pix[x,y][0]]
-                try:
-                    pix_alpha = val[3] # the color image has transparency
-                except IndexError:
-                    pix_alpha = OPAQUE # it doesn't
-                
-
-                # Blend the opacities
-                # ===================
-
-                conf, pixel = self.opacity, pix_alpha
-                if (conf, pixel) not in _computed_opacities:
-                    opacity = int(( (conf/255.0)    # from configuration
-                                  * (pixel/255.0)   # from per-pixel alpha
-                                   ) * 255)
-                    _computed_opacities[(conf, pixel)] = opacity
-                
-                pix[x,y] = val[:3] + (_computed_opacities[(conf, pixel)],)
-
-    
-    def save(self):
-        self.img.save(self.fspath, 'PNG')
-
-
Index: src/django_gheat/gheat/pygame_.py
===================================================================
--- src/django_gheat/gheat/pygame_.py	(revision 9823)
+++ 	(revision )
@@ -1,143 +1,0 @@
-import os
-
-import numpy
-import pygame
-from gheat import SIZE, base
-
-
-WHITE = (255, 255, 255)
-
-
-# Needed for colors
-# =================
-# 
-#   http://www.pygame.org/wiki/HeadlessNoWindowsNeeded 
-# 
-# Beyond what is said there, also set the color depth to 32 bits.
-
-os.environ['SDL_VIDEODRIVER'] = 'dummy'
-pygame.display.init()
-pygame.display.set_mode((1,1), 0, 32)
-
-
-class ColorScheme(base.ColorScheme):
-
-    def hook_set(self, fspath):
-        colors = pygame.image.load(fspath)
-        self.colors = colors = colors.convert_alpha()
-        self.color_map = pygame.surfarray.pixels3d(colors)[0] 
-        self.alpha_map = pygame.surfarray.pixels_alpha(colors)[0]
-
-    def hook_build_empty(self, opacity, fspath):
-        tile = pygame.Surface((SIZE,SIZE), pygame.SRCALPHA, 32)
-        tile.fill(self.color_map[255])
-        tile.convert_alpha()
-
-        (conf, pixel) = opacity, self.alpha_map[255]
-        opacity = int(( (conf/255.0)    # from configuration
-                      * (pixel/255.0)   # from per-pixel alpha
-                       ) * 255)
-
-        pygame.surfarray.pixels_alpha(tile)[:,:] = opacity 
-        pygame.image.save(tile, fspath)
-
-
-class Dot(base.Dot):
-    def hook_get(self, fspath):
-        img = pygame.image.load(fspath)
-        half_size = img.get_size()[0] / 2
-        return img, half_size
-
-
-class Tile(base.Tile):
-
-    def hook_rebuild(self, points):
-        """Given a list of points, save a tile.
-    
-        This uses the Pygame backend.
-   
-        Good surfarray tutorial (old but still applies):
-
-            http://www.pygame.org/docs/tut/surfarray/SurfarrayIntro.html
-
-        Split out to give us better profiling granularity.
-
-        """
-        tile = self._start()
-        tile = self._add_points(tile, points)
-        tile = self._trim(tile)
-        tile = self._colorize(tile)
-        return tile
-
-
-    def _start(self):
-        tile = pygame.Surface(self.expanded_size, 0, 32)
-        tile.fill(WHITE)
-        return tile
-        #@ why do we get green after this step?
- 
-       
-    def _add_points(self, tile, points):
-        for dest in points:
-            tile.blit(self.dot, dest, None, pygame.BLEND_MULT)
-        return tile
-
-
-    def _trim(self, tile):
-        tile = tile.subsurface(self.pad, self.pad, SIZE, SIZE).copy()
-        #@ pygame.transform.chop says this or blit; this is plenty fast 
-        return tile
-
-
-    def _colorize(self, tile):
-
-        # Invert/colorize
-        # ===============
-        # The way this works is that we loop through all pixels in the image,
-        # and set their color and their transparency based on an index image.
-        # The index image can be as wide as we want; we only look at the first
-        # column of pixels. This first column is considered a mapping of 256
-        # gray-scale intensity values to color/alpha.
-
-        # Optimized: I had the alpha computation in a separate function because 
-        # I'm also using it above in ColorScheme (cause I couldn't get set_alpha
-        # working). The inner loop runs 65536 times, and just moving the 
-        # computation out of a function and inline into the loop sped things up 
-        # about 50%. It sped it up another 50% to cache the values, since each
-        # of the 65536 variables only ever takes one of 256 values. Not super
-        # fast still, but more reasonable (1.5 seconds instead of 12).
-        #
-        # I would expect that precomputing the dictionary at start-up time 
-        # should give us another boost, but it slowed us down again. Maybe 
-        # since with precomputation we have to calculate more than we use, the 
-        # size of the dictionary made a difference? Worth exploring ...
-
-        _computed_opacities = dict()
-
-        tile = tile.convert_alpha(self.color_scheme.colors)
-        tile.lock()
-        pix = pygame.surfarray.pixels3d(tile)
-        alp = pygame.surfarray.pixels_alpha(tile)
-        for x in range(SIZE):
-            for y in range(SIZE):
-                key = pix[x,y,0]
-
-                conf, pixel = self.opacity, self.color_scheme.alpha_map[key]
-                if (conf, pixel) not in _computed_opacities:
-                    opacity = int(( (conf/255.0)    # from configuration
-                                  * (pixel/255.0)   # from per-pixel alpha
-                                   ) * 255)
-                    _computed_opacities[(conf, pixel)] = opacity
-
-                pix[x,y] = self.color_scheme.color_map[key]
-                alp[x,y] = _computed_opacities[(conf, pixel)]
-
-        tile.unlock()
-   
-        return tile
-
-
-    def save(self):
-        pygame.image.save(self.img, self.fspath)
-
-
Index: src/django_gheat/gheat/settings.py
===================================================================
--- src/django_gheat/gheat/settings.py	(revision 9823)
+++ 	(revision )
@@ -1,99 +1,0 @@
-# Django settings for persisted project.
-
-import os
-PROJECT_HOME = os.path.dirname(__file__)
-
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-
-ADMINS = (
-    # ('Your Name', 'your_email@domain.com'),
-)
-
-MANAGERS = ADMINS
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-        'NAME': 'project_heatmap',                      # Or path to database file if using sqlite3.
-        'USER': 'root',                      # Not used with sqlite3.
-        'PASSWORD': 'password',                  # Not used with sqlite3.
-        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
-        'PORT': '3306',                      # Set to empty string for default. Not used with sqlite3.
-    }
-}
-
-# Local time zone for this installation. Choices can be found here:
-# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
-# although not all choices may be available on all operating systems.
-# If running in a Windows environment this must be set to the same as your
-# system time zone.
-TIME_ZONE = 'America/Chicago'
-
-# Language code for this installation. All choices can be found here:
-# http://www.i18nguy.com/unicode/language-identifiers.html
-LANGUAGE_CODE = 'en-us'
-
-SITE_ID = 1
-
-# If you set this to False, Django will make some optimizations so as not
-# to load the internationalization machinery.
-USE_I18N = True
-
-# Absolute path to the directory that holds media.
-# Example: "/home/media/media.lawrence.com/"
-MEDIA_ROOT = ''
-
-# URL that handles the media served from MEDIA_ROOT. Make sure to use a
-# trailing slash if there is a path component (optional in other cases).
-# Examples: "http://media.lawrence.com", "http://example.com/media/"
-MEDIA_URL = ''
-
-# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
-# trailing slash.
-# Examples: "http://foo.com/media/", "/media/".
-ADMIN_MEDIA_PREFIX = '/media/'
-
-# Make this unique, and don't share it with anybody.
-SECRET_KEY = '=wg@x19kr@26sibiaynb9ax5ddp1&yu^+$3n++^_lz1ms80syb'
-
-# List of callables that know how to import templates from various sources.
-TEMPLATE_LOADERS = (
-    'django.template.loaders.filesystem.load_template_source',
-    'django.template.loaders.app_directories.load_template_source',
-#     'django.template.loaders.eggs.load_template_source',
-)
-
-MIDDLEWARE_CLASSES = (
-    'django.middleware.common.CommonMiddleware',
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    'django.contrib.auth.middleware.AuthenticationMiddleware',
-)
-
-ROOT_URLCONF = 'persisted.urls'
-
-TEMPLATE_DIRS = (
-    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
-    # Always use forward slashes, even on Windows.
-    # Don't forget toABQIAAAA6NuvWGazX80RVrkSkvrUXBQuY05VDPolZO1YI32txJLc5t1HWBRafKMBWIXOpS9wazP_0ErZiNd8_g use absolute paths, not relative paths.
-    os.path.join(PROJECT_HOME, 'templates'),
-    
-)
-
-INSTALLED_APPS = (
-    'django.contrib.auth',
-    'django.contrib.contenttypes',
-    'django.contrib.sessions',
-    'django.contrib.sites',
-    'gheat',
-    'django_extensions',
-    'home',
-    'django.contrib.admin',
-)
-
-#GOOGLE_MAPS_KEY = 'ABQIAAAA2icoFs7d_hisx8EBdZy-mxQF3fr7joqA35-x6JbT4Kx-pk-_6xRkPVambEqUO33n_8g9KWVaLKq8UA' # localhost
-#GOOGLE_MAPS_KEY = 'ABQIAAAAnfs7bKE82qgb3Zc2YyS-oBT2yXp_ZAY8_ufC3CFXhHIE1NvwkxSySz_REpPq-4WZA27OwgbtyR3VcA' # external ip
-GOOGLE_MAPS_KEY = 'ABQIAAAA6NuvWGazX80RVrkSkvrUXBTpH3CbXHjuCVmaTc5MkkU4wO1RRhSZXiYEMqjgwJ9gi_PC8AA-dDGz6g' # 127.0.0.1:8000
-
-
-
Index: src/django_gheat/gheat/urls.py
===================================================================
--- src/django_gheat/gheat/urls.py	(revision 9823)
+++ src/django_gheat/gheat/urls.py	(revision 10615)
@@ -1,11 +1,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls.defaults import *
-
-urlpatterns = patterns('gheat.views',
-    url(
-        # Example : today/fire/12/3,2.png
-        regex = r'^(?P<color_scheme>\w+)/(?P<zoom>\d+)/(?P<x>\d+),(?P<y>\d+).png$',
-        view = 'serve_tile',
-        name = 'serve_tile',
-       ),
-    )
Index: src/django_gheat/gheat/views.py
===================================================================
--- src/django_gheat/gheat/views.py	(revision 9823)
+++ 	(revision )
@@ -1,69 +1,0 @@
-import os.path
-from django.http import HttpResponseRedirect
-from gheat import dots
-from gheat import backend, color_schemes, translate, ROOT, log, \
-        ALWAYS_BUILD
-
-from django.http import HttpResponseBadRequest
-from django.conf import settings
-from django.views.static import serve
-
-# Create your views here.
-def serve_tile(request,color_scheme,zoom,x,y):
-    '''
-        Responsible for serving png files of the tile for the heat map
-
-        This view will try to serve the file from the filesystem in case already
-        exists otherwise just try to genereate it, and serve it.
-    '''
-
-    # Asserting request is a correct one
-    try:
-        assert color_scheme in color_schemes, ( "bad color_scheme: "
-                                              + color_scheme
-                                               )
-        assert zoom.isdigit() and x.isdigit() and y.isdigit(), "not digits"
-        zoom = int(zoom)
-        x = int(x)
-        y = int(y)
-        assert 0 <= zoom <= 22, "bad zoom: %d" % zoom
-    except AssertionError, err:
-        return HttpResponseBadRequest()
-
-    # @TODO: We should return the file in case is already present
-    # Also we have to implement a redirection to the front end in case we are not in debug mode ... should we ? 
-
-    fspath = generate_tile(request,color_scheme,zoom,x,y)
-
-    if settings.DEBUG:
-        return serve(request, fspath, '/')
-    else:
-        return HttpResponseRedirect(fspath.replace(ROOT, '/site_media/gheat/'))
-
-
-def generate_tile(request,color_scheme,zoom,x,y):
-    '''
-        This view will generate the png file for the current request
-    '''
-    path = request.path
-
-    path = path[path.index(color_scheme)-1:] # Removing the /gheat/ from the url
-
-    fspath = translate(ROOT, path)
-
-    if os.path.exists(fspath):
-        return fspath
-
-    color_scheme = color_schemes[color_scheme]
-    tile = backend.Tile(color_scheme, dots, zoom, x, y, fspath)
-    if tile.is_empty():
-        fspath = color_scheme.get_empty_fspath(zoom)
-        log.debug('serving empty tile, request: %s, file %s' % (path,fspath))
-    elif tile.is_stale() or ALWAYS_BUILD:
-        log.debug('rebuilding %s' % path)
-        tile.rebuild()
-        tile.save()
-    else:
-        log.debug('serving cached tile %s' % path)
-
-    return fspath
Index: src/django_gheat/httpd/maps.conf
===================================================================
--- src/django_gheat/httpd/maps.conf	(revision 9823)
+++ src/django_gheat/httpd/maps.conf	(revision 10615)
@@ -14,4 +14,6 @@
   RedirectMatch temp ^/$ /d/wlheatmap/
   Alias /d/static /usr/local/django_gheat/sitestatic
+  WSGIDaemonProcess maps processes=2 threads=15 display-name=%{GROUP}
+  WSGIProcessGroup maps
   WSGIScriptAlias /d /usr/local/django_gheat/django.wsgi
   <Directory /usr/local/django_gheat>
Index: src/django_gheat/httpd/osmproxy.conf
===================================================================
--- src/django_gheat/httpd/osmproxy.conf	(revision 9823)
+++ src/django_gheat/httpd/osmproxy.conf	(revision 10615)
@@ -18,4 +18,8 @@
   </Proxy>
   # Example /7/63/43.png
+  <Location /osm-tile-proxy>
+    Order allow,deny
+    Allow from all
+  </Location>
   ProxyPassMatch ^/osm-tile-proxy/(\d{1,2}/\d{1,6}/\d{1,6}\.png)$ balancer://osmcluster/$1 lbmethod=byrequests
   CacheEnable disk /osm-tile-proxy/
Index: src/django_gheat/wlheatmap/tile.py
===================================================================
--- src/django_gheat/wlheatmap/tile.py	(revision 9823)
+++ src/django_gheat/wlheatmap/tile.py	(revision 10615)
@@ -16,12 +16,4 @@
 import time
 
-# Rending with PIL and computation with numpy has proven to be to slow to be
-# usable, but is still in here for refence purposes.
-try:
-  from PIL import Image
-  import ImageDraw
-  import numpy as np
-except ImportError:
-  pass
 
 class PyGamePicture():
@@ -70,46 +62,4 @@
       pygame.draw.circle(new_surf,combined_colour,center,r,0)
     self.surf.blit(new_surf,(0,0),special_flags=pygame.BLEND_RGBA_MAX)
-
-
-class PILPicture():
-  """ Basic PIL class, allowing simple image manipulations """
-  im = None
-  def __init__(self, method, size):
-    self.im = Image.new(method, size)
-    self.data = np.array(self.im)
-
-  def write(self,fh,format='png'):
-        self.im.save(fh,format)
-
-  def make_circle(self,draw, center, radius,colour=(0,255,0)):
-    """ Cicle gradient is created by creating smaller and smaller cicles """
-    (center_x, center_y) = center
-    for i in range(0,radius):
-      draw.ellipse(
-        (center_x - radius + i,
-         center_y - radius + i,
-         center_x + radius - i,
-         center_y + radius - i
-        ),
-        colour +(255 * i/(radius * 2),)
-      )
-
-  def add_circle(self, center, radius, colour):
-    """ Adding a new cicle is a matter of creating a new one in a empty layer
-    and merging it with the current one 
-
-    XXX: Very heavy code, should actually only work on the data arrays, instead
-    of doing all the magic with high-level images """
-
-    im_new = Image.new("RGBA", self.im.size)
-    draw = ImageDraw.Draw(im_new)
-    self.make_circle(draw, center, radius, colour)
-    
-    data2 = np.array(im_new)
-    
-    # Add channels to make new images
-    self.data = self.data + data2
-    self.im = Image.fromarray(self.data)
-
 
 
