Last active
May 6, 2020 07:58
-
-
Save bahoo/4daef0a59e6ccb2cc9329ad58f8de7d3 to your computer and use it in GitHub Desktop.
Compression / low bandwidth / lower file size tricks with shapefiles / GeoDjango / GIS / Django
This file contains hidden or 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
# 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