Index: src/django_gheat/website/tile.py
===================================================================
--- src/django_gheat/website/tile.py	(revision 9147)
+++ src/django_gheat/website/tile.py	(revision 9148)
@@ -13,26 +13,33 @@
 import settings
 import sys
+import pygame
+import tempfile
 
-log = logging.getLogger('sample_tile')
-logging.basicConfig(level=logging.DEBUG)
-setup_environ(settings)
+logging.basicConfig(level=logging.WARNING)
+log = logging.getLogger('tile')
+
+class PyGamePicture():
+  """ Basic PyGame class, allowing simple image manipulations """
+  def __init__(self, method, size):
+    self.surf = pygame.Surface(size,flags=pygame.SRCALPHA)
+
+  def write(self, fh,format='png'):
+    # XXX: How to get a PNG stream directly to the output
+    f = tempfile.NamedTemporaryFile(suffix=format)
+    pygame.image.save(self.surf,f.name)
+    f.seek(0)
+    fh.write(f.read())
 
 
-def make_circle(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=(255,0,0)):
+    # Quirky hack to generate lineair gradient circles and merge them with the parent.
+    new_surf = pygame.Surface((250,250),flags=pygame.SRCALPHA)
+    for r in range(radius,1,-1):
+      pygame.draw.circle(new_surf,colour + (255 - (r * (float(255)/radius)),),center,r,0)
+    self.surf.blit(new_surf,(0,0),special_flags=pygame.BLEND_RGBA_MAX)
 
 
-class Picture():
-  """ Basic class, allowing simple image manipulations """
+class PILPicture():
+  """ Basic PIL class, allowing simple image manipulations """
   im = None
   def __init__(self, method, size):
@@ -40,6 +47,19 @@
     self.data = np.array(self.im)
 
-  def save(self,*args, **kw):
-        self.im.save(*args, **kw)
+  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):
@@ -52,5 +72,5 @@
     im_new = Image.new("RGBA", self.im.size)
     draw = ImageDraw.Draw(im_new)
-    make_circle(draw, center, radius, colour)
+    self.make_circle(draw, center, radius, colour)
     
     data2 = np.array(im_new)
@@ -103,10 +123,14 @@
 def make_tile(x,y,z):
   """ Crude attempt to generate tiles, by placing a gradient circle on a
-  coordinate point. Many stuff NOT implemented yet, like:
-  * Caching Images
-  * Behaviour around edges (generate larger imagea)
+  coordinate point.
+  
+  Many stuff NOT implemented yet, like:
+  - Caching Images
+  - Generate a larger tile (300x300) at first and then crop it to the required
+    size (250x250).
   """
   nw_deg,se_deg = boundbox_deg(x,y,z)
   
+  Picture = PyGamePicture
   resolution_deg = nw_deg.deg_per_pixel(se_deg, 250)
   im = Picture("RGBA",(250,250))
@@ -119,10 +143,12 @@
      latitude__lte=nw_deg.lat,latitude__gte=se_deg.lat,
      longitude__lte=se_deg.lon,longitude__gte=nw_deg.lon)
-  if metingen.count() > 100:
-    metingen = metingen[1:100]
   
   def dif(x,y):
     return max(x,y) - min(x,y)
   
+  # Converting LatLon to Meters is discussed here:
+  #  http://stackoverflow.com/questions/3024404/transform-longitude-latitude-into-meters
+  tile_height = float(40008000) / (2 ** z)
+  meters_per_pixel = float(tile_height) / 250
   for meting in metingen:
     lat_min = min(lat_min, meting.latitude)
@@ -133,5 +159,11 @@
     ycoord = dif(nw_deg.lat,meting.latitude) / (resolution_deg.lat)
     log.info(meting.accespoint.ssid, meting.latitude, meting.longitude, xcoord, ycoord)
-    im.add_circle((xcoord,ycoord),z,(255,0,0))
+    # The radius relates to the zoom-level we are in, and should represent
+    # a fixed distance, given the scale. Assume signal/distance to be lineair
+    # such that signal 100% = 100m and 1% = 1m.
+    # 
+    # XXX: The relation is not lineair but from a more logeritmic scape, as we
+    # are dealing with radio signals
+    im.add_circle((xcoord,ycoord),float(meting.signaal) / meters_per_pixel,(255,0,0))
   
   log.info("BoundingBox NW: %s" % nw_deg)
@@ -150,8 +182,9 @@
   im = make_tile(int(x),int(y),int(zoom))
   response = HttpResponse(mimetype="image/png")
-  im.save(response, 'PNG')
+  im.write(response,'png')
   return response
 
 if __name__ == '__main__':
+  log.setLevel(logging.DEBUG)
   x = int(sys.argv[1])
   y = int(sys.argv[2])
@@ -160,4 +193,4 @@
   im = make_tile(x,y,z)
   filename = 'sample-gradient.png'
-  im.save(filename)
-  log.info("#INFO: Output saved as '%s'" % filename)
+  im.write(open(filename,'w'))
+  log.info("Output saved as '%s'" % filename)
