Thursday 27 August 2015

Displaying/feeding US census/tiger data into Google Maps API?


Let's say I want to display age, income, etc based on census block groups on Google maps.


How can I do this and also to allow simple queries?




Answer



I have spent a lot of time mapping block groups and found that rendering them as tiles is usually the most efficient option.


Client Side Flash Rendering: Max = Counties


The most detailed geography you can reasonably expect a client browser to render on a national scale is US Counties and even those require significant optimization. The NY Times has a nice example of the max polygon rendering you can expect in a client side app using flash. However, this solution doesn't work on the IPAD or most mobile devices. The load is pretty efficient (about 400k for the initial flash app and fewer ongoing requests) and light on server requirements. Nearly equal (a bit slower) performance is possible with canvas, but cross browser support is lacking (IE 7 & 8). You can use Google's Explorer Canvas as a bridge for IE but it is too slow for US Counties, and it will be a years before network speeds make it practical to have a browser download the 100MB+ of polygon data needed to draw every Block Group in the client.


Zoom Level Swapping Strategy: Reveal Details as you zoom in


The NY Times also has a nice example of swapping between layer types as a user zooms in and our. Bigger, County sized shapes are shown when zoomed out and smaller shapes when zoomed in. The benefit of this kind of configuration is that, when done right, it will give users a really nice experience without putting much rendering demand on the server. The downside to this kind of setup is that it is fiddly to get right, requires editorial decisions to be controlled by technical limits (ie designers and programmers have to talk a lot) and it will never give you a national view of block group shapes.


Server Side Tiles + Client Html: Max = Unlimited


Server side rendering puts more pressure on your GIS server stack because it is doing all the heavy lifting. The nice thing about server side rendering is that your rendering is done in a controlled environment where you can manage the resources and code top to bottom and render nearly any size dataset. The client just downloads tile and metadata on demand and renders them as pure html. The bottleneck in this approach becomes server throughput and the network bandwidth required to serve hundreds of small requests. Here is a map performance white paper that breaks down the load profile of a typical Google Map, Zillow map and some other custom tile layers. For top level zooms caching makes sense, but as you go deeper the number of tiles becomes large enough that Disk IO can be a bottleneck. Web Mercator Maps (ie google tiles) require (2^zoom * 2^zoom) tiles per zoom level, and rendering a national map with a reasonable level of detail can require millions of tiles even if you skip duplicates. The ideal solution is to have a dynamic server + static cache of difficult regional tiles combo that is fast enough at rendering tiles that you don't have to worry about pre-rendering millions of tiles in bulk. If you can render tiles on the fly you can empower designers and even users to create, filter and restyle the maps without creating an admin ticket.


Here is an example of Census Block Groups and several other large datasets rendered nationally on google maps using a tile configuration.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...