Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am using leaflet.js to allow web users to select a region. Valid regions are US states, Canadian providences, and world countries (except for US and Canada). I constructed a shapefile myself using Qgis and saved it as a geojson. I simplified the geometries as much as I could.

The resulting shapefile is 400kb, but the geojson is over a megabyte. This is bigger than I would like. I need to reduce the network overhead involved in transferring this information.

What is the right way to do this? The options I can imagine are:

  1. Serve the geojson file gzipped, unpack on the client.
  2. Parse the shapefile on the client to geojson
  3. Generate my own tiles from the shapefile and serve those

If anyone could tell me which option is the best (or none of the above) I would appreciate it!

share|improve this question
    
I note that you said you tried to simplify the geometry, but have you tried using a GIS simplification algorithm and checking the results? It might also help to look at which part of the JSON is taking up the most space. –  BradHards Jan 14 '13 at 5:58
    
Make sure the GeoJSON is not pretty-printed, stripping out all unnecessary white space will help make the file smaller - not necessarily by a huge amount but it all helps! –  CHenderson Sep 5 '13 at 21:23
add comment

4 Answers

Before going down any more laborious paths, the simplest option is to reduce the geometry. What are your source datasets? How did you simplify them? How much did this reduce the geojson file size?

If you are confident that you have done all you can on the above, then the lowest hanging fruit of your options is

  1. Serve the geojson file gzipped, unpack on the client.

All modern browsers do the unpacking of gzipped data automatically, so it's just a case of setting up your web server to pack up the data before sending. This is normally a relatively straight forward, with much material around out there for Apache, IIS or Nginx

My tip would be to try this first, test, then if latency / response / data size is not acceptable, then move to other options. I would also be wary of trying to optimise prematurely, I would be looking to determine why you need to reduce the data size, and once you have hard reasons (and numbers) for doing so, then iteratively implementing changes and re testing to see what gains you are getting.

share|improve this answer
add comment

I wonder if you could make use of the compression found in this answer that talks about compressing the GeoJSON with topojson.

I don't know if Leaflet will still be able to read the GeoJSON - something to try =)

More about topojson: https://github.com/mbostock/topojson/

share|improve this answer
    
Leaflet.GeoJSON doesn't parse arc data, so this approach won't work –  smcphill Feb 7 '13 at 0:28
    
Leaflet can't natively but you can use topojson on the client side to do it, example of topojson on leaflet, though that example happens to use d3 to render it. –  Calvin Feb 16 '13 at 19:28
add comment

I agree with @Kelso above on simplifying your geometry.

If you don't have access to your server to deflate the data with gzip easily you could take a look at the MessagePack library to serialise your geoJSON into binary data (I believe it's an implementation of the BSON spec that's used by things like MongoDB to store data, but I could be wrong). There are libraries in Python and javascript (among others) that you can use to serialise/deserialise the data.

share|improve this answer
2  
MessagePack is not related to BSON (it's actually better in many cases according to stackoverflow.com/questions/6355497/…. More interesting info about messagepack and specifically geojson can be found at nelsonslog.wordpress.com/2012/06/22/checking-out-msgpack. –  Kelso Jan 14 '13 at 23:27
    
Thanks for that @Kelso - updated the answer. And good article too! –  om_henners Jan 15 '13 at 4:25
add comment

I would suggest just creating your own procedural array of Leaflet Polygon objects. I agree with GeoJSON being way too big. The object key names are very descriptive but maybe unnecessarily long as well. I do this kind of thing:

objects = [];
objects.push( new L.polygon([[1,1],[1,2],[3,4]],options );
objects.push( new L.polygon([[4,7],[8,27],[35,66]],options );
objects.push( new L.polygon([[3,5],[56,24],[13,49]],options );
objects.push( new L.polygon([[13,7],[7,68],[23,9]],options );
layerGroup = L.layerGroup(objects).addTo(map);

It's straightforward. It's much more lightweight than GeoJSON like this:

{ "type": "FeatureCollection",
  "features": [
    { "type": "Feature",
      "geometry": {"type": "Polygon",
      "coordinates": [1,1],[1,2],[3,4]},
      },

    //etc...

And Repeat for every single polygon... ugh... way too bloated imo. Adds a lot of bytes to your JS. Like I said, the key names are nice and descriptive... but they are long and add a lot of unnecessary byes to your JS.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.