Skip to content

Instantly share code, notes, and snippets.

@ebrelsford
Created May 16, 2013 15:07
Show Gist options
  • Save ebrelsford/5592416 to your computer and use it in GitHub Desktop.
Save ebrelsford/5592416 to your computer and use it in GitHub Desktop.
Get clusters from a GeoDjango model that could be used in a heatmap (eg, using Heatmap.js), including potentially dynamic filters on the model.
from django.db import connection, DEFAULT_DB_ALIAS
num_clusters = 6
queryset = model.objects.filter() # Your filters here
queryset = queryset.filter(centroid__isnull=False).only('centroid')
# Get the query for
sql_model_query, params = queryset.query.get_compiler(DEFAULT_DB_ALIAS).as_sql()
# Requires Postgresql with the kmeans extension
cluster_query = """
SELECT kmeans AS id, count(*), ST_Centroid(ST_Collect(centroid)) AS centroid
FROM (
SELECT kmeans(ARRAY[ST_X(centroid), ST_Y(centroid)], %d) OVER (), centroid
FROM (%s) as centroid
) AS ksub
GROUP BY kmeans
ORDER BY kmeans
""" % (num_clusters, sql_model_query)
counts = []
max_count = 0
# Execute the query
cursor = connection.cursor()
cursor.execute(cluster_query, params)
for cluster in cursor.fetchall():
# Assemble a heatmap.js-friendly dict
id, count, centroid = cluster
max_count = max(max_count, count)
centroid = GEOSGeometry(centroid)
counts.append({
'lat': centroid.y,
'lon': centroid.x,
'value': count,
})
heatmap_data = {
'max': max_count,
'data': counts,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment