Changeset 9184


Ignore:
Timestamp:
May 12, 2011, 12:05:59 PM (14 years ago)
Author:
rick
Message:

Implemented cross database tile caching method, using base64 storage.

Location:
src/django_gheat
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/django_gheat/gheat/models.py

    r9179 r9184  
    1 from django.db import models
    21from gheat import managers
    32import datetime
     3import binascii
     4import hashlib
     5
     6from django.core import validators
     7from django.db import models
     8from django.dispatch import receiver
     9from django.utils.encoding import smart_unicode
     10from django.utils.translation import ugettext_lazy as _
     11
     12class BinaryField(models.Field):
     13  MAGIC = '###MAGIC###'
     14  description = _('Binary object using base64 (up to %(max_length)s)')
     15
     16  __metaclass__ = models.SubfieldBase
     17
     18  def __init__(self, *args, **kwargs):
     19    # base64 roughly max the binary size with with 4 times
     20    kwargs['max_length'] = kwargs['max_length'] * 4 + len(self.MAGIC)
     21    super(BinaryField, self).__init__(*args, **kwargs)
     22    self.validators.append(validators.MaxLengthValidator(self.max_length))
     23
     24  def to_python(self,value):
     25    if value.startswith(self.MAGIC):
     26      return binascii.a2b_base64(value[len(self.MAGIC):])
     27    else:
     28      return value
     29
     30  def get_db_prep_value(self, value, connection, prepared=False):
     31    target = self.MAGIC + binascii.b2a_base64(value)
     32    if len(target) > self.max_length:
     33      raise ValueError(len(target))
     34    return target
     35
     36  def get_prep_lookup(self, lookup_type, value):
     37    raise TypeError('Lookup type %r not supported.' % lookup_type)
     38
     39  def get_internal_type(self):
     40    return 'TextField'
     41
     42class TileCache(models.Model):
     43  key = models.CharField(max_length=34,unique=True)
     44  data = BinaryField(max_length=10000)
     45  creation_time = models.DateTimeField(auto_now_add=True)
     46
     47  def __unicode__(self):
     48    return self.key
     49
     50  @staticmethod
     51  def make_key(source):
     52    return hashlib.md5(source).hexdigest()
     53
    454
    555class Accespoint(models.Model):
  • src/django_gheat/website/tile.py

    r9174 r9184  
    1212import sys
    1313import tempfile
     14import time
    1415
    1516# Rending with PIL and computation with numpy has proven to be to slow to be
     
    2223  pass
    2324
    24 logging.basicConfig(level=logging.WARNING)
     25logging.basicConfig(level=logging.DEBUG)
    2526log = logging.getLogger('tile')
    2627
     
    4445    f.seek(0)
    4546    fh.write(f.read())
     47
     48  def get_image(self,format='png'):
     49    f = tempfile.NamedTemporaryFile(suffix=format)
     50    pygame.image.save(self.surf,f.name)
     51    f.seek(0)
     52    return f.read()
    4653
    4754
     
    222229    xcoord = int(dif(nw_deg.lon,meting.longitude) / (resolution_deg.lon))
    223230    ycoord = int(dif(nw_deg.lat,meting.latitude) / (resolution_deg.lat))
    224     log.info(meting.accespoint.ssid, meting.latitude, meting.longitude, xcoord, ycoord)
    225231
    226232    # TODO: Please note that this 'logic' technically does apply to WiFi signals,
     
    238244    signal_normalized = MAX_RANGE - (MAX_SIGNAL - meting.signaal)
    239245    im.add_circle((xcoord,ycoord),float(signal_normalized) / meters_per_pixel,colour, MAX_SIGNAL - meting.signaal)
     246    #im.add_point((xcoord,ycoord),float(signal_normalized) / meters_per_pixel,colour, MAX_SIGNAL - meting.signaal)
    240247 
    241248  log.info("BoundingBox NW: %s" % nw_deg)
     
    253260# Create your views here.
    254261def serve_tile(request,zoom,x,y):
    255   filter = {}
    256   colour = (255,0,0)
    257   for key, value in request.GET.iteritems():
    258     if key == 'colour':
    259       colour = tuple(map(int,value.split(',')))
    260     else:
    261       filter[key] = value
    262   im = make_tile(int(x),int(y),int(zoom),filter=filter,colour=colour)
     262  hash_key = TileCache.make_key("%s %s %s %s" % (zoom, x ,y, request.GET.urlencode()))
     263  try:
     264    d = TileCache.objects.get(key=hash_key)
     265    data = d.data
     266  except TileCache.DoesNotExist:
     267    #log.setLevel(logging.DEBUG)
     268    filter = {}
     269    colour = (255,0,0)
     270    for key, value in request.GET.iteritems():
     271      if key == 'colour':
     272        colour = tuple(map(int,value.split(',')))
     273      else:
     274        filter[key] = value
     275    now = time.time()
     276    im = make_tile(int(x),int(y),int(zoom),filter=filter,colour=colour)
     277    log.info("Processing time: %s" % (time.time() - now))
     278    data = im.get_image('png')
     279    r = TileCache.objects.create(key=hash_key,data=data)
     280
    263281  response = HttpResponse(mimetype="image/png")
    264   im.write(response,'png')
     282  response.write(data)
    265283  return response
     284
Note: See TracChangeset for help on using the changeset viewer.