Created
November 1, 2011 21:10
-
-
Save albertsun/1331918 to your computer and use it in GitHub Desktop.
geojson tiles views.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from redistricting.apps.features.models import CensusBlock, CensusTract, CensusCounty, DataBlock | |
from redistricting.utils import gmerc | |
from django.http import HttpResponse, Http404, HttpResponseForbidden | |
from django.contrib.gis.geos import GEOSGeometry | |
from django.shortcuts import render_to_response | |
from django.template.loader import render_to_string | |
from django.template import RequestContext | |
from django.core import serializers | |
from django.views.decorators.cache import cache_page | |
import json | |
import time | |
# def blocks_by_bounds(request): | |
# """ | |
# /geom/CensusBlocksBox/?bbox=42.864637,-88.891514,42.94645,-79.43732 | |
# """ | |
# return features_bounds(request, DataBlock) | |
# def tracts_by_bounds(request): | |
# return features_bounds(request, CensusTract) | |
# def features_bounds(request, GeomClass): | |
# """ | |
# /geom/<FeatureType>sBox/?bbox=42.864637,-88.891514,42.94645,-79.43732 | |
# """ | |
# bbox = request.GET.get('bbox', '') | |
# jsonpcallback = request.GET.get('callback','') | |
# if bbox == '': | |
# raise Http404 | |
# # has lat lngs in this order: SWNE | |
# bbox = bbox.split(',') | |
# # TODO: to ease scaling, will probably have to round these off and memcached the result | |
# bbox_wkt = "POLYGON((" | |
# bbox_wkt += bbox[1]+" "+bbox[0]+"," | |
# bbox_wkt += bbox[1]+" "+bbox[2]+"," | |
# bbox_wkt += bbox[3]+" "+bbox[2]+"," | |
# bbox_wkt += bbox[3]+" "+bbox[0]+"," | |
# bbox_wkt += bbox[1]+" "+bbox[0] | |
# bbox_wkt += "))" | |
# box_geom = GEOSGeometry(bbox_wkt, srid=4326) | |
# cbs = GeomClass.objects.filter(the_geom__intersects = box_geom) | |
# return _output_geo_queryset(cbs, jsonpcallback) | |
@cache_page(60*60*24*7) | |
def serve_block_tiles(request, z, x, y): | |
""" | |
/geom/CensusBlockTile/<z>/<x>/<y>.json | |
For example: | |
/geom/CensusBlockTile/16/19302/24633.json | |
""" | |
z,x,y = [int(z), int(x), int(y)] | |
assert isinstance(z, int), TypeError("zoom must be an int from 0 to 30") | |
assert isinstance(x, int), TypeError("x must be an int") | |
assert isinstance(y, int), TypeError("y must be an int") | |
if (z < 13): | |
return HttpResponse(json.dumps([]), mimetype="application/json") | |
else: | |
return serve_tile(request, z, x, y, DataBlock) | |
def serve_tile(request, z, x, y, GeomClass): | |
""" | |
/geom/<FeatureType>Tile/<z>/<x>/<y>.json | |
""" | |
jsonpcallback = request.GET.get('callback','') | |
# Translate tile coordinates into lat-lng bounds | |
x1 = x * 256 | |
x2 = x1 + 255 | |
y1 = y * 256 | |
y2 = y1 + 255 | |
n, w = gmerc.px2ll(x1, y1, z) | |
s, e = gmerc.px2ll(x2, y2, z) | |
s,w,n,e = [str(s), str(w), str(n), str(e)] | |
bbox_wkt = "".join(["POLYGON((", | |
w+" "+s+",", | |
w+" "+n+",", | |
e+" "+n+",", | |
e+" "+s+",", | |
w+" "+s, | |
"))"]) | |
box_geom = GEOSGeometry(bbox_wkt, srid=4326) | |
cbs = GeomClass.objects.filter(the_geom__intersects = box_geom) | |
return _output_geo_queryset(cbs, jsonpcallback) | |
def _output_geo_queryset(qs, jsonpcallback=""): | |
""" | |
Helper function that takes a query set and returns the geometries and info as json. | |
Uses a JSONP callback if one is specified | |
""" | |
#Bleh. this bit is pretty ugly | |
try: | |
geoms = { "type": "FeatureCollection", | |
"features": [{ 'id': c.geoid10, 'type': 'Feature', 'geometry': json.loads(c.the_geom.json), 'properties': serializers.serialize('python', [c])[0]['fields'] } for c in qs] | |
} | |
if (len(geoms) == 0): | |
return HttpResponse(json.dumps([]), mimetype="application/json") | |
assert('totpop' in geoms['features'][0]['properties']), AttributeError("Doesn't have population info") | |
except AttributeError: | |
geoms = { "type": "FeatureCollection", | |
"features": [{ 'id': c.geoid10, 'geometry': json.loads(c.the_geom.json), 'properties': None } for c in qs] | |
} | |
if (jsonpcallback != ''): | |
out = jsonpcallback + '(' + json.dumps(geoms) + ')' | |
else: | |
out = json.dumps(geoms) | |
resp = HttpResponse(out, mimetype="application/json") | |
resp['X-ALBERT'] = "=)" | |
return resp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment