Mapping the Census with PostGIS, Python, and a whole lot of stubbornness
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Moss, Keith
Bowland, Graham
Mapping the Census with PostGIS, Python, and a whole lot of stubbornness: A Vector Tiles Story
 Let's talk about the sensors. For the past couple of years, I've spent some time with a good friend of mine building what we call ILGIS, the ALGIS. And so it opens up a mapping tool to let almost anyone with any skill level explore and analyze the data from the sensors, which is a large data set maintained by the ABS. I'll be covering sort of two parts of this story today. We'll sort of start out with while we built some of the challenges for the average person in trying to use sensor data, and some of our ideas from knocking down some of those barriers. Then we'll sort of talk a bit about how we built it, how we use post-its and vector tiles, and how they're amazing, essentially. So the sensors, I think really is like the ultimate open data set we have. It's this ginormous longitudinal data set that covers 94. something percent of the population. It's a huge, rich resource. It's got 400 different topics in it from how long it takes you to get to work in the morning to whether you live in a house, a flat, or a houseboat. But using it in a spatial context has a few challenges. You can use the sensors in quite a few ways already. You can go and download it. The ABS and other organizations make tools and maps and reports available about particular broad themes in the sensors, about employment or housing and so forth. ABS has TableBuilder, which is a really powerful tool, but you need to be a bit of an ABS data nerd to take time to learn and understand and use it properly. So if what you're interested in falls outside those bands of pre-generated report or sort of powerful stats tools, then you quite quickly hit the bar of having to work with raw sensors data itself or getting someone in to do that work for you. And the ABS does a really, really good job of making it, the sensors available. You can go and grab the whole thing. Free, crowd-com license, it's easier to access, but this is sort of what you get in the download. This is one of the CSVs from the 2016 census. There's 7,000 of those in the nice big zip data set. It requires a favorite skill to go from this to a map if you're not a diary person or a gist person or a mapping person. You can go from like cutting a question about data to having a result is 5, 6, 7, 8 steps of data geocoding and so forth. So we thought we can probably tackle these barriers where smartly write code with no spatial stuff. What if we did a sort of thing like Excel for maps in that sense? Excel's widely used already. It's relatively simple conceptually to understand and use, but you've got this sort of path of expressions that anyone that can understand and write those stuff, combine and transform data themselves without having to write code or understand that that database is in so forth. We didn't want folks to think about finding the data, don't learn it, extracting it all, finding the right data set, geocoding that data set to LGA or SA1s and so forth, and then finally getting onto a map in some fashion, in some service. We didn't believe what we had to know about spatial or projections or GIS or anything, but we know they just want to see something on a map to try and sort of short circuit that process. We also kind of wanted to take some gatekeepers out of the system in the same way that Excel can remove the need for a database and a DBA and so forth. Access to the census data and data like this shouldn't necessarily need a GIS person or an IT person and so forth. Take some of those sort of knocks out of the system. And this is what I thought would work on this Excel for Maps concept looks like so far. That looks all cool. So I've chosen the Subobes data set from the 2016 census and because this is Melbourne, we'll find some data about Melbourne. So I'm curious to know where folks in the UK have come in Melbourne, where they sort of settled around the greater Melbourne area. So we'll look at country of birth by person. So this is a sort of segmented data set of where were you born from the census by age range and so forth. So here we're just sort of grabbing folks from Northern Ireland and Scotland and you can see it's just sort of this plus this type of expression. In the same way Excel is A1 plus B1 plus B3. And we'll choose Wales. So yeah, quite simple expression. And we'll see what it looks like on a map and we'll make some tweaks to the styling to add some more colour ranges and turn off the scaling on the data and so forth. And that is our data mapped on Scots in the Northern Irish. There's no need to know about GISTs or how do you get your data into a system. From here you might want to look at proportion of population or combine it with some other variable from some other table of the census and so forth. And that's all just the sort of Excel style expression away once you've found it. So another hood in the technical level. This is kind of what we're doing. So we're sort of taking this user's expression of G1 by 70 and G162 are those sort of the internal census IDs, translating that into essentially a whole pile of SQL at the other side through taking the case of the sub-abs geometry and then passing that expression out to those individual databases and the columns and so forth in there. And then through SQL Alchemy spitting out a pile of SQL that's like this join, so this connects to this and bam that's the entire data set built sort of on the fly for whatever that expression is. We'll talk about how that gets to the map bit in a sec. But yeah, for us it would be just sort of our idea for how do we get some more powerful data analysis tools and database tools into the hands of more people using these sort of big data sets like the census which are kind of still locked down to folks like us that work with data. First and foremost, for us it's something we built for the community. Anyone can use the sort of public community site we've got set up. They can run their own Ilvius. It's all open source and free obviously. Already loaded with the 2011 and 2016 census. Really it's there to let folks iterate quickly, question to expression to map in that fashion as well. We have a couple of happy users as well. So I think Greens have been helping us sort of beta test it for the past five years since we hacked together a group of concept. I've got 30-odd users also around the country know that planning various campaigning efforts with it from sort of big national level questions right down to my local suburb, my local electorate type things. For them it's taking the sort of the back end and they're thinking about the data out of the picture. Their IT and special volunteers don't need to get requests for maps from individual campaigns. Electrics about we'd like to see number of renters or people doing at home childcare and so forth. They can set up for their users and they can just go and get their maps and sort of self-serve in that way when they have a question about something. So in building Ilvius we had a couple of sort of key points around data transparency and verifiability. We wanted to keep in front of our minds it's too easy to make a mistake in either choosing the wrong data set or making an assumption that's incorrect about a data set or just trusting that what you see on the map is actually an accurate representation of the data. So for us, two key points there. One is there's no secret source in how the data gets in there. Data ingest process is published, documented and it's up on GitHub, openly licensed. You can go and check it, verify, rerun it and so forth. And there's no trust us element either. It's you can go from that map that we saw then, grab it as a CSV file, compare that to the actual raw census data and make sure that calculations of the data are actually correct so it's not going to be verified for you and so forth. It's also called any sort of data. It's we chose census because it was large, useful and it was there. Anything with the concept of location there, electoral data, survey data and so forth can also be applied to it. So now the kind of the how we bulked all this stuff together. I could talk for far, far longer than the six minutes I have left about how we actually got the census usable in a spatial context, how we built data loaders for about six months to get CSV into post-its and how we passed all the interesting metadata, the ABS's publishes about the census. But this is a spatial conference and I mentioned the vector tile story so let's talk more about vector tiles. Steve kind of have this good rundown of prize and cons, what you should use it for when you shouldn't use it. For those who aren't here, vector tile essentially is a small little packet of simplified and compressed spatial data and attribute data. But all the styling, the rendering, the presentation happens in the browser. So unlike WMS, it's not like a pre-computed tile. You just get data and attributes and then you style that in your web browser or whatever. For those who want the full picture, I've got some notes in the presentation notes with links to other presentations and sort of in-depth dives into how, what's the why's of vector tiles as well. So we looked at vector tiles as a solution for this census mapping for a couple of reasons. The first was because of data itself. Census is ginormous, 400 plus data tables, 57,000 potential variables in there about everything around the country. So we couldn't really take the usual approaches of pre-generating a bunch of data sets, pre-running analysis and so forth. It wasn't going to scale, it wasn't going to be practical for us. So vector tiles were kind of a nicer option there. And this sort of Excel for maps conflict introduced a few more challenges. Users can take any of those 57,000 variables, mash them together in some way and create a sort of new data set on the fly. So again, we couldn't sort of pre-compute that analysis. But we still wanted users to be able to sort of go quite quickly from expression to map to concept like that, with having to wait around something to run on the back end. You also need to support any level of data. So from a national level summary right down to the smallest mesh block of 50 houses somewhere, had to sort of work and be fast as well. And the text that had to be simple. So we sort of run this ourselves, sort of our own pockets. It's a community tool that we're very keen to keep developing and supporting. But to do that, running costs had to be low for it to be a viable thing for us. And specter tiles came to the rescue for us. Let's just sort of achieve all of that. This code here, don't try and read it quite small. This is all that's required to take that sort of SQL query generated by the expression fuzzer and spit out some vector tiles to the client for us. It's... You can then go and use that in open layers of leaflet and so forth. So it's pretty agnostic about the environment. And that's all coming straight out of post-gis. And this is kind of a... It's not the most elegant post-gis functions and so forth. But these are the two sort of key functions required to get vector tiles that are post-gis. There's a... As-MBT, which sort of takes individual rows and transforms them into vector tiles. And as-MBT-GOM, which is kind of the geometry side of that, taking that and transforming that into the coordinate space of vector tiles. There is a ton of really good presentations and resources online about how that actually works under the hood. There's some in the speakers' notes as well. But just to reiterate, these are all built on the fly from whatever the user has entered as an expression. And they form insanely well. Most of them are happening in less than half a second for even the most sort of complex expression at SA1 messbox level. So QDOS to folks that put that into post-gis. That has been a... It's fantastic to see that sort of on-the-fly generation of stuff when you have dynamic data sets. So for us, it's great. It's super fast. Because we're that close to the data, we can start to do a few more optimizations. So we can still throw out geometries that are too small. If you've got a big tile of Sydney, you don't want every single individual mesh block or SA1. Any ones you can see. And being still simplified geometries and do other sort of custom optimizations as well. It's super lightweight. The sort of community site right now runs on a five to a lot of months digital ocean droplet, a single CPU and a single RAM. And that's the entire post-gis Django engines stack and so forth in there. So for us, this sort of single SQL query replaced... We'll press our entire GeoServer instance that we needed for this. There's someone that's built lots of Mac server, GeoServer stacks in the past that still slightly scary. Because that's kind of been the big complex spatial bit that sort of served us. But, boiling it back down to SQL just kind of feels refreshing and powerful in the same sense that we can do so much with seemingly so little these days for use cases like this. I think as Steve mentioned for us in GeoServer plugins for effective tiles as well. So if you have a GeoServer, you can just pop that in and play with that straight away. So thanks in closing. Without the amazing work of the ABS in running, maintaining and doing the sensors over the past 100 odd years, none of this would work. And likewise, everyone working on post-gis and post-gres and SQL coming in open layers and so forth. We are really just standing on this whole, there's many, many giants before us that have built this ecosystem of tooling and codes and platforms and so forth. So thank you to anyone here that works on those. Very much appreciated. And thank you for your time today. So you can check out the public community site at DELON.geoGIS.org and all the repos are on GitHub. Take a look there. We would warmly welcome anyone that wants to work on any aspect of this. We're a friendly community of two developers right now. And you can read our code of conduct in the repo as well. For us, it'll just as a sort of work in progress over the next couple of years. We're looking at upgrading expressions to include functions and so forth, a lot of completion, and some general UX improvements on the application. And lastly, a small present for anyone that likes to work with data. You can grab our postage stumps from that link there. So that's the fully specialized census and has all the parsed ABS metadata. So you can link individual variables to what they actually mean in reality. That's just sort of JSON queryable rather than the God-awful spreadsheet that the ABS publishes. Thank you. Have fun. Excuse me, rather than downloading all the CSV files and building the Excel expression, wouldn't it be easier to use the SDMX, the SDMX service from ABS? Why did you discard that? For us, it didn't contain everything we needed. For us, it didn't contain all the data we needed. So it wasn't the full census at the time. It was only a cut of the main topics. I mean, we wanted to be able to combine those variables on the fly and do it quite quickly. So we looked at SDMX and first thought, great, an API. And then sort of hit some sort of practical barriers of, actually, that's not going to work in reality. But we'd love to use it, use it a bit more in the future in terms of just pulling the SDMX data set that we haven't got, perhaps, some of the non-census stuff. All right. Okay. I was just wondering whether you attempted anything with the time series of data from the ABS? We've got the time series profile in there, yeah. That's from the census. Yeah, that's loaded in there, yeah. Thank you.
 Let's talk about the sensors. For the past couple of years, I've spent some time with  a good friend of mine building what we call ILGIS, the ALGIS. And so it opens up a mapping  tool to let almost anyone with any skill level explore and analyze the data from the sensors,  which is a large data set maintained by the ABS. I'll be covering sort of two parts of  this story today. We'll sort of start out with while we built some of the challenges  for the average person in trying to use sensor data, and some of our ideas from knocking  down some of those barriers. Then we'll sort of talk a bit about how we built it, how we  use post-its and vector tiles, and how they're amazing, essentially. So the sensors, I think  really is like the ultimate open data set we have. It's this ginormous longitudinal  data set that covers 94. something percent of the population. It's a huge, rich resource.  It's got 400 different topics in it from how long it takes you to get to work in the morning  to whether you live in a house, a flat, or a houseboat. But using it in a spatial context  has a few challenges. You can use the sensors in quite a few ways already. You can go and  download it. The ABS and other organizations make tools and maps and reports available  about particular broad themes in the sensors, about employment or housing and so forth.  ABS has TableBuilder, which is a really powerful tool, but you need to be a bit of an ABS data  nerd to take time to learn and understand and use it properly. So if what you're interested  in falls outside those bands of pre-generated report or sort of powerful stats tools, then  you quite quickly hit the bar of having to work with raw sensors data itself or getting  someone in to do that work for you. And the ABS does a really, really good job of making  it, the sensors available. You can go and grab the whole thing. Free, crowd-com license,  it's easier to access, but this is sort of what you get in the download. This is one  of the CSVs from the 2016 census. There's 7,000 of those in the nice big zip data set.  It requires a favorite skill to go from this to a map if you're not a diary person or a  gist person or a mapping person. You can go from like cutting a question about data to  having a result is 5, 6, 7, 8 steps of data geocoding and so forth. So we thought we can  probably tackle these barriers where smartly write code with no spatial stuff. What if we  did a sort of thing like Excel for maps in that sense? Excel's widely used already. It's  relatively simple conceptually to understand and use, but you've got this sort of path  of expressions that anyone that can understand and write those stuff, combine and transform  data themselves without having to write code or understand that that database is in so  forth. We didn't want folks to think about finding the data, don't learn it, extracting  it all, finding the right data set, geocoding that data set to LGA or SA1s and so forth,  and then finally getting onto a map in some fashion, in some service. We didn't believe  what we had to know about spatial or projections or GIS or anything, but we know they just  want to see something on a map to try and sort of short circuit that process. We also  kind of wanted to take some gatekeepers out of the system in the same way that Excel can  remove the need for a database and a DBA and so forth. Access to the census data and data  like this shouldn't necessarily need a GIS person or an IT person and so forth. Take  some of those sort of knocks out of the system. And this is what I thought would work on this  Excel for Maps concept looks like so far. That looks all cool. So I've chosen the Subobes  data set from the 2016 census and because this is Melbourne, we'll find some data about  Melbourne. So I'm curious to know where folks in the UK have come in Melbourne, where they  sort of settled around the greater Melbourne area. So we'll look at country of birth by  person. So this is a sort of segmented data set of where were you born from the census  by age range and so forth. So here we're just sort of grabbing folks from Northern Ireland  and Scotland and you can see it's just sort of this plus this type of expression. In the  same way Excel is A1 plus B1 plus B3. And we'll choose Wales. So yeah, quite simple expression.  And we'll see what it looks like on a map and we'll make some tweaks to the styling  to add some more colour ranges and turn off the scaling on the data and so forth. And  that is our data mapped on Scots in the Northern Irish. There's no need to know about GISTs  or how do you get your data into a system. From here you might want to look at proportion  of population or combine it with some other variable from some other table of the census  and so forth. And that's all just the sort of Excel style expression away once you've  found it. So another hood in the technical level. This is kind of what we're doing. So  we're sort of taking this user's expression of G1 by 70 and G162 are those sort of the  internal census IDs, translating that into essentially a whole pile of SQL at the other  side through taking the case of the sub-abs geometry and then passing that expression  out to those individual databases and the columns and so forth in there. And then through  SQL Alchemy spitting out a pile of SQL that's like this join, so this connects to this and  bam that's the entire data set built sort of on the fly for whatever that expression  is. We'll talk about how that gets to the map bit in a sec. But yeah, for us it would  be just sort of our idea for how do we get some more powerful data analysis tools and  database tools into the hands of more people using these sort of big data sets like the  census which are kind of still locked down to folks like us that work with data. First  and foremost, for us it's something we built for the community. Anyone can use the sort  of public community site we've got set up. They can run their own Ilvius. It's all open  source and free obviously. Already loaded with the 2011 and 2016 census. Really it's  there to let folks iterate quickly, question to expression to map in that fashion as well.  We have a couple of happy users as well. So I think Greens have been helping us sort of  beta test it for the past five years since we hacked together a group of concept. I've  got 30-odd users also around the country know that planning various campaigning efforts  with it from sort of big national level questions right down to my local suburb, my local electorate  type things. For them it's taking the sort of the back end and they're thinking about  the data out of the picture. Their IT and special volunteers don't need to get requests  for maps from individual campaigns. Electrics about we'd like to see number of renters  or people doing at home childcare and so forth. They can set up for their users and  they can just go and get their maps and sort of self-serve in that way when they have a  question about something. So in building Ilvius we had a couple of sort of key points around  data transparency and verifiability. We wanted to keep in front of our minds it's too easy  to make a mistake in either choosing the wrong data set or making an assumption that's incorrect  about a data set or just trusting that what you see on the map is actually an accurate  representation of the data. So for us, two key points there. One is there's no secret  source in how the data gets in there. Data ingest process is published, documented and  it's up on GitHub, openly licensed. You can go and check it, verify, rerun it and so forth.  And there's no trust us element either. It's you can go from that map that we saw then,  grab it as a CSV file, compare that to the actual raw census data and make sure that  calculations of the data are actually correct so it's not going to be verified for you  and so forth. It's also called any sort of data. It's we chose census because it was  large, useful and it was there. Anything with the concept of location there, electoral  data, survey data and so forth can also be applied to it. So now the kind of the how  we bulked all this stuff together. I could talk for far, far longer than the six minutes  I have left about how we actually got the census usable in a spatial context, how we  built data loaders for about six months to get CSV into post-its and how we passed all  the interesting metadata, the ABS's publishes about the census. But this is a spatial conference  and I mentioned the vector tile story so let's talk more about vector tiles. Steve kind of  have this good rundown of prize and cons, what you should use it for when you shouldn't  use it. For those who aren't here, vector tile essentially is a small little packet  of simplified and compressed spatial data and attribute data. But all the styling, the  rendering, the presentation happens in the browser. So unlike WMS, it's not like a pre-computed  tile. You just get data and attributes and then you style that in your web browser or  whatever. For those who want the full picture, I've got some notes in the presentation notes  with links to other presentations and sort of in-depth dives into how, what's the why's  of vector tiles as well. So we looked at vector tiles as a solution for this census mapping  for a couple of reasons. The first was because of data itself. Census is ginormous, 400 plus  data tables, 57,000 potential variables in there about everything around the country.  So we couldn't really take the usual approaches of pre-generating a bunch of data sets, pre-running  analysis and so forth. It wasn't going to scale, it wasn't going to be practical for  us. So vector tiles were kind of a nicer option there. And this sort of Excel for maps conflict  introduced a few more challenges. Users can take any of those 57,000 variables, mash them  together in some way and create a sort of new data set on the fly. So again, we couldn't  sort of pre-compute that analysis. But we still wanted users to be able to sort of go quite  quickly from expression to map to concept like that, with having to wait around something  to run on the back end. You also need to support any level of data. So from a national level  summary right down to the smallest mesh block of 50 houses somewhere, had to sort of work  and be fast as well. And the text that had to be simple. So we sort of run this ourselves,  sort of our own pockets. It's a community tool that we're very keen to keep developing  and supporting. But to do that, running costs had to be low for it to be a viable thing  for us. And specter tiles came to the rescue for us. Let's just sort of achieve all of  that. This code here, don't try and read it quite small. This is all that's required  to take that sort of SQL query generated by the expression fuzzer and spit out some vector  tiles to the client for us. It's... You can then go and use that in open layers of leaflet  and so forth. So it's pretty agnostic about the environment. And that's all coming straight  out of post-gis. And this is kind of a... It's not the most elegant post-gis functions  and so forth. But these are the two sort of key functions required to get vector tiles  that are post-gis. There's a... As-MBT, which sort of takes individual rows and transforms  them into vector tiles. And as-MBT-GOM, which is kind of the geometry side of that, taking  that and transforming that into the coordinate space of vector tiles. There is a ton of really  good presentations and resources online about how that actually works under the hood. There's  some in the speakers' notes as well. But just to reiterate, these are all built on the fly  from whatever the user has entered as an expression. And they form insanely well. Most of them  are happening in less than half a second for even the most sort of complex expression  at SA1 messbox level. So QDOS to folks that put that into post-gis. That has been a...  It's fantastic to see that sort of on-the-fly generation of stuff when you have dynamic  data sets. So for us, it's great. It's super fast. Because we're that close to the data,  we can start to do a few more optimizations. So we can still throw out geometries that  are too small. If you've got a big tile of Sydney, you don't want every single individual  mesh block or SA1. Any ones you can see. And being still simplified geometries and do other  sort of custom optimizations as well. It's super lightweight. The sort of community site  right now runs on a five to a lot of months digital ocean droplet, a single CPU and a  single RAM. And that's the entire post-gis Django engines stack and so forth in there.  So for us, this sort of single SQL query replaced... We'll press our entire GeoServer instance  that we needed for this. There's someone that's built lots of Mac server, GeoServer stacks  in the past that still slightly scary. Because that's kind of been the big complex spatial  bit that sort of served us. But, boiling it back down to SQL just kind of feels refreshing  and powerful in the same sense that we can do so much with seemingly so little these  days for use cases like this. I think as Steve mentioned for us in GeoServer plugins for  effective tiles as well. So if you have a GeoServer, you can just pop that in and play  with that straight away. So thanks in closing. Without the amazing work of the ABS in running,  maintaining and doing the sensors over the past 100 odd years, none of this would work.  And likewise, everyone working on post-gis and post-gres and SQL coming in open layers  and so forth. We are really just standing on this whole, there's many, many giants before  us that have built this ecosystem of tooling and codes and platforms and so forth. So thank  you to anyone here that works on those. Very much appreciated. And thank you for your time  today. So you can check out the public community site at DELON.geoGIS.org and all the repos  are on GitHub. Take a look there. We would warmly welcome anyone that wants to work on  any aspect of this. We're a friendly community of two developers right now. And you can read  our code of conduct in the repo as well. For us, it'll just as a sort of work in progress  over the next couple of years. We're looking at upgrading expressions to include functions  and so forth, a lot of completion, and some general UX improvements on the application.  And lastly, a small present for anyone that likes to work with data. You can grab our  postage stumps from that link there. So that's the fully specialized census and has all the  parsed ABS metadata. So you can link individual variables to what they actually mean in reality.  That's just sort of JSON queryable rather than the God-awful spreadsheet that the ABS  publishes. Thank you. Have fun.  Excuse me, rather than downloading all the CSV files and building the Excel expression,  wouldn't it be easier to use the SDMX, the SDMX service from ABS? Why did you discard  that?  For us, it didn't contain everything we needed. For us, it didn't contain all the data we  needed. So it wasn't the full census at the time. It was only a cut of the main topics.  I mean, we wanted to be able to combine those variables on the fly and do it quite quickly.  So we looked at SDMX and first thought, great, an API. And then sort of hit some sort of  practical barriers of, actually, that's not going to work in reality. But we'd love to  use it, use it a bit more in the future in terms of just pulling the SDMX data set that  we haven't got, perhaps, some of the non-census stuff.  All right. Okay. I was just wondering whether you attempted anything with the time series  of data from the ABS?  We've got the time series profile in there, yeah. That's from the census. Yeah, that's  loaded in there, yeah.  Thank you.
Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_0_887.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_888_2735.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_2736_3095.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_3096_3227.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_3228_3347.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_3348_3395.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_3396_3707.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_3708_5591.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_5592_5723.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_5724_5927.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_5928_7979.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_7980_9575.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_9576_10031.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_10032_12743.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_12744_14459.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_14460_16007.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_16008_16535.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_16536_17243.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_17244_23855.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_23856_24047.png Keith_Moss__Mapping_the_Census_with_PostGIS__Python__and____Uj61skz4spE_24048_24302.png