Permalink
Browse files

Working with GeoDjango model and spatialitedb. gheat.Tile now require…

…s a queryset with a PointField and optionally last_modified and density fields.
  • Loading branch information...
1 parent fc95a76 commit 269ffc0017bfb9afdecf624739cb033771296389 Timothy Caro-Bruce committed Nov 23, 2009
Showing with 35 additions and 27 deletions.
  1. +26 −19 gheat/base.py
  2. +3 −5 gheat/models.py
  3. +2 −1 gheat/views.py
  4. BIN samples/persisted/db/persisted.db
  5. +4 −2 samples/persisted/templates/home.html
View
@@ -4,10 +4,11 @@
import stat
from django.core.exceptions import ImproperlyConfigured
+from django.contrib.gis.geos import Polygon
import gheat
import gheat.opacity
-from gheat.models import Point
+#from gheat.models import Point
from gheat import gheatsettings as settings
from gheat import gmerc
from gheat import BUILD_EMPTIES, DIRMODE, SIZE, log
@@ -98,7 +99,7 @@ class Tile(object):
img = None
- def __init__(self, color_scheme, dots, zoom, x, y, fspath):
+ def __init__(self, queryset, color_scheme, dots, zoom, x, y, fspath, point_field='geometry', last_modified_field=None, density_field=None):
"""x and y are tile coords per Google Maps.
"""
@@ -149,22 +150,28 @@ def __init__(self, color_scheme, dots, zoom, x, y, fspath):
self.x2 = x2
self.y2 = y2
- self.expanded_size = expanded_size
- self.llbound = (n,s,e,w)
+ self.expanded_size = expanded_size
+ self.bbox = Polygon.from_bbox((w,s,e,n))
self.zoom = zoom
self.fspath = fspath
self.opacity = gheat.opacity.zoom_to_opacity[zoom]
self.color_scheme = color_scheme
-
+
+ self.queryset = queryset
+ self.point_field = point_field
+ self.last_modified_field = last_modified_field
+ self.density_field = density_field
+
+ def features_inside(self):
+ return self.queryset.filter(**{self.point_field + "__intersects": self.bbox})
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 = Point.objects.num_points(self)
- return numpoints == 0
+ return not bool(self.features_inside()[:1])
def is_stale(self):
@@ -173,16 +180,13 @@ def is_stale(self):
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):
+ if not self.last_modified_field or not os.path.isfile(self.fspath):
return True
timestamp = os.stat(self.fspath)[stat.ST_MTIME]
modtime = datetime.datetime.fromtimestamp(timestamp)
- numpoints = Point.objects.num_points(self, modtime)
-
- return numpoints > 0
-
+ return bool(self.features_inside().filter(**{self.last_modified_field + "__gt":modtime})[:1])
def rebuild(self):
"""Rebuild the image at self.img. Real work delegated to subclasses.
@@ -192,21 +196,24 @@ def rebuild(self):
# =================
# 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.
+
+ fields = [self.point_field]
+ if self.density_field:
+ fields.append(self.density_field)
+ _points = self.features_inside().values(*fields)
- _points = Point.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)
+ for feature_dict in _points:
+ point = feature_dict[self.point_field]
+ x, y = gmerc.ll2px(point.y, point.x, self.zoom)
x = x - self.x1 # account for tile offset relative to
y = y - self.y1 # overall map
- point_density = point.density
- while point_density > 0:
+ point_density = feature_dict.get(self.density_field, 1)
+ for i in range(point_density):
result.append((x-self.pad,y-self.pad))
- point_density = point_density - 1
return result
View
@@ -1,20 +1,18 @@
-from django.db import models
-from gheat import managers
+from django.contrib.gis.db import models
# Create your models here.
class Point(models.Model):
"""
A simple representation of a point inside the gheat database
"""
uid = models.CharField(max_length=100, name='unique identifier')
- latitude = models.FloatField(name='Latitude', db_column='lat', blank=True)
- longitude = models.FloatField(name='Longitude', db_column='lng', blank=True)
+ geometry = models.PointField()
modtime = models.DateTimeField(auto_now = True,
name='Last modification time', null=True)
density = models.PositiveIntegerField(default=0, editable=False,
name='density of the current point')
- objects = managers.PointManager()
+ objects = models.GeoManager()
class Meta:
unique_together = ('uid',)
View
@@ -3,6 +3,7 @@
from gheat import dots
from gheat import backend, color_schemes, translate, ROOT, log, \
ALWAYS_BUILD
+from gheat.models import Point
from django.http import HttpResponseBadRequest
from django.conf import settings
@@ -55,7 +56,7 @@ def generate_tile(request,color_scheme,zoom,x,y):
return fspath
color_scheme = color_schemes[color_scheme]
- tile = backend.Tile(color_scheme, dots, zoom, x, y, fspath)
+ tile = backend.Tile(Point.objects.all(), color_scheme, dots, zoom, x, y, fspath, last_modified_field='modtime')
if tile.is_empty():
fspath = color_scheme.get_empty_fspath(zoom)
log.debug('serving empty tile, request: %s, file %s' % (path,fspath))
Binary file not shown.
@@ -28,8 +28,10 @@
function initialize () {
var map = new GMap2(document.getElementById("map"));
- var lebanon = new GLatLng(52.390268,4.890976);
- map.setCenter(lebanon, 8);
+ var toronto = new GLatLng(43.5,-79.2);
+ map.addControl(new GSmallMapControl());
+ map.addControl(new GMapTypeControl());
+ map.setCenter(toronto, 7);
map.addOverlay(new GTileLayerOverlay(heatmap));
}

0 comments on commit 269ffc0

Please sign in to comment.