Skip to content

Instantly share code, notes, and snippets.

@bahoo
Last active May 6, 2020 07:58
Show Gist options
  • Save bahoo/4daef0a59e6ccb2cc9329ad58f8de7d3 to your computer and use it in GitHub Desktop.
Save bahoo/4daef0a59e6ccb2cc9329ad58f8de7d3 to your computer and use it in GitHub Desktop.
Compression / low bandwidth / lower file size tricks with shapefiles / GeoDjango / GIS / Django
# put lots of SEO friendly terms in the title for Googlers / Stack Overflow crawlers like myself...
# basically, tricks to make pulling down shapefiles much smaller file size, ergo faster web sites
# control test was 1.2MB of GeoJSON for three polygon shapes...
from django.contrib.gis.db.models.functions import AsGeoJSON
from django.db.models.expressions import RawSQL
from django.views.generic import TemplateView
from .models import City
class MapView(TemplateView):
template_name = "map.html"
def get_context_data(self, **kwargs):
context = super(MapView, self).get_context_data(**kwargs)
# ST_Simplify is a big help. Given a certain tolerance, it will simplify your polygon to crunch it down
# from the real world dimensions to something perfectly suitable for web use
# ST_SimplifyPreserveTopology is also worth a look
simplified = RawSQL('ST_Simplify(map_city.geom, 0.0005)', ())
# this is a Django hack; AsGeoJSON is expecting a geometry, not an expression
# this gives it a fake srid to satisfy https://github.com/django/django/blob/3c447b108ac70757001171f7a4791f493880bf5b/django/contrib/gis/db/models/functions.py#L50-L52
simplified.srid = True
# AsGeoJSON('simplified', precision=3) is the other big piece here
# ST_Simplify() cuts extraneous points, but that precision= parameter cuts lots of extra digits being sent across the wire
context['cities'] = City.objects.select_related('state').defer('state__geom').annotate(simplified=simplified, geojson=AsGeoJSON('simplified', precision=3)).all()
# These pieces alone can cut ~400kb of GeoJSON down to ~3.8KB
# ALSO RECOMMEND -- GZip encoding: https://docs.djangoproject.com/en/1.10/ref/middleware/#module-django.middleware.gzip
# final filesize cut down to 3.8kb (!)
return context
# original -- 1.2mb (three polygons)
# adding GZip -- 356kb (70% compression ratio)
# adding ST_Simplify -- 8.6kb (97% compression ratio)
# adding precision=3 -- 3.5kb (55% compression ratio)
# will update this when I have more data points to test with; I suspect the numbers will change as number of polygons change...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment