 And I work for Imaginary Landscape and I've been doing Jenga development for about four years. I wanted to talk to you today about a topic I find really interesting and that's GeoJango and GIS applications. So a little bit of background about how I got into this. A few years back, Chicago had a mobile app building competition and they made available a data portal for the city for use with this competition and other reasons. And I built a simple little app that kind of showed various cool interesting things to do around CTA train stops. And though I didn't win any awards for this, it kind of inspired me to learn more about this technology over the next few years. And I continued to build on this project and play with it and some of the examples from this talk are going to be straight out of that project. So first I'd like to cover a few general definitions that I found useful. One of them is a coordinate reference system and this is a system to locate geospatial entities on a map and there are two basic types. There's geographic coordinate systems which represent the Earth as a sphere or spheroid and there's projected coordinate systems which project maps into a flat surface. And you've probably heard all the problems with projected coordinate systems in that you get map distortions if you flatten a map from a sphere. So they're particularly good at representing local data and not so much like zoomed out data. So coordinate systems are important because data could be encoded in any number of coordinate systems and you need a way to like normalize that data so you can perform math and display them on the same map. So a coordinate system registry is another thing. The primary registry is called the EPSG and this is an authority that like catalogs and maintains different coordinate systems and it uniquely identifies coordinate systems by a spatial reference ID and so that's how spatial reference systems are kind of named is based off that ID. There's a great resource called spatialreference.org which is a nice index for coordinate systems and it has a lot of information about each system and defines the definition of the coordinate systems in a variety of different formats. One very common coordinate system that you'll encounter a lot if you use this is WSG84 and it's a geographic coordinate system meaning it represents the Earth as a sphere or spheroid and it's used by the GPS system so you'll find a lot of data encoded in this system. It also goes by the name EPSG 4326 which is the spatial reference ID for it so you'll probably encounter this a bunch. I like to talk about Postgres and PostGIS and I personally when I use GeoJango my preferred back end of choice is PostGIS and Postgres, first of all I love Postgres and GeoJango typically has better support or more functions available for Postgres so it's a good choice for working with GeoData. And PostGIS once you're a major update not too long ago to a version 2.0 update and it's become a lot easier to install for an Ubuntu 14.04 system you just need to install a bunch of app dependencies and switch to the database you want to use and run a create extension command. It's now an extension so it's really easy to get started working with it on a new system. I've also included a link on here you'll be able to see in the slides for just some quick installation steps for Ubuntu 14.04 and CentOS 7. So I'm going to refer to this diagram a few times throughout the talk it's basically the architecture stack that I'm going to build up and let's assume that we've gone through the Django tutorial and installed GeoJango and hooked it up with our PostGIS database and this is what we have so far this is what it will look like. A few other notes about PostGIS when you run that extension it will create a bunch of different objects in your database it will create functions and stored procedures to do geometric operations but it will also create a new table called the spatial refsys table. This is basically a tableized form of the data from spatialreference.org it has the spatial reference IDs and different definitions for the coordinate systems that GeoJango or PostGIS can use to do conversions between coordinate systems. Also there's two new views that will be created in your database one called the geometry columns and one called geography columns views and these identify which columns in your database are spatially enabled previous to PostGIS 2.0 these were tables and not views so you had to manually maintain these tables but well if you use GeoJango GeoJango would take care of that for you but as of 2.0 you don't no longer have to do that since they're views and they're dynamically calculated. So one thing when you're working with after we've got the database set up and GeoJango set up the next question is where do I get data and I found my data source on Chicago's data portal which was great there was like hundreds of different data files that I can use but there's data sources all over the place I was really surprised every major city has their own data portal it seems like you just do a Google and you'll find a lot of example data you can play with so and that's just the open data you can get. Another place to get data is the open street map project and this is kind of like a crowd sourced Wikipedia of maps thing and data is available under an open license so you can get a lot of data out of this website it's a pretty cool site and tool. So now we've identified some potential data sources and these sources provide data in all sorts of formats and now we have to import those formats import that data into the database so we can start using it. So there's a few serialization formats I'd like to talk about and the first one is called a well-known text and this is just a string-based format for identifying geometry so here's some examples of point objects and string objects they're just basic text representations of the geometry that you can load into your database. Well-known text is used in a lot of places and including one of the columns in the spatial refsys table defines each coordinate system in well-known text format so it's not only for geographic data it's also for defining reference systems. So Django has built-in support for loading well-known text data with using this OGR geometry class which takes a constructor argument for your geography or geometry data and it will create a Python object that you can then assign to a model or do whatever you want with. Another serialization format is called Keyhole Markup Language you might have heard of it's KML and it's an XML-based format developed by Keyhole Inc which was then bought up by Google and is now used in Google Earth. So it's obviously a good format for sending data to Google Maps and to Google Earth but it's a serialization format so you can use it however you want. There's some Python utilities called Simple KML and Fast KML that you can use to load and manipulate data in KML. GeoJSON is another obvious choice for serialization format and it's developed and maintained by a independent group on the internet so there's no specific authority it's just like a mailing list of people that define how this format should work and it's a JSON representation of your data and it's a nice option to send data to a browser if you're you know because JavaScript is nice to work with in the browser. There's a good Python utility for working with this on the Python level called GeoJSON. All of these formats are serializable by GeoJango so you can print out various geometry objects in these respective formats. And finally I'd like to mention Shapefile format which is an extremely common format for persisting geospatial data to files specifically and it was a format developed by the ESRI which is a company that makes a very popular open or a very popular product called ArcGIS for geospatial data. It's an expensive program but it's used in the industry a bunch. And Shapefiles are kind of misnamed because they're not really a single file they're a collection of files so you'll find at least three files in a Shapefile archive. It's usually like a zip or something but each file has a different purpose and you can have up to like 10 or so different files representing the same geometry. GeoJango has some support for loading this type of object using this data source class. You can import Shapefile data and also there's a Python library called PyShape which you can use to help get data into your application. So you can create a Python based importer using the tools I just mentioned or you can take advantage of some command line tools to load this data. One of them is Shape2PGSQL or OGR to OGR. I'm not gonna get into detail on those but they're very powerful and they have a lot of different options you can pass to them to import different types of geodata. So I'd like to talk a little bit about server-based geo utilities. And the first one is the project reproach for library which is a dependency for GeoJango and it's responsible for converting between different projections. And also the spatial ref-sys table in post-GIS has a column called Proj4Text which also stores a definition for a projection in Proj4 format. So there's an additional, that's what Proj4 can use to do map projection conversions. Also I've used Proj4 or more specifically a Python wrapper for called PyProj to translate coins on a map. And in my particular use case, I filled in a shape with evenly spaced points by transforming a single point into multiple directions. And I use this for generating a group of source points for creating a heat map. Another great utility for working with data on the server side, geodata on the server side is called MapNIC. And it's basically a tool that you use if you want to render maps to images. And it's great for, there's a lot of pythons to port for it. It's got some Python bindings. So you can write, you can use this tool to write just flat JPEGs or images that you can use in reports. We can also, you can also, you can also can be used by a map tiling engine, which I'll talk about in a little bit. So here's our stack architecture diagram again. You'll notice I added MapNIC to it. And you see it's making a direct connection to post-GIS. And MapNIC supports a variety of different data sources. Shapefiles, CSV, GeoJSON. And in the last slide you saw post-GIS. And each data source is added as a layer. So it kind of takes a layered approach and top most layers show up on top. But one of the nice features about MapNIC is the fact that you can style your maps. Just GeoData by itself isn't very useful unless you can visually represent it. So it's got a pretty sophisticated way to style data. You can either use this Python API to build up styles or you can create an XML style definition that you can load and use to style your different data layers. So here's a very simple MapNIC example. And I'm using the XML style sheet in this example. So I'm loading the XML file, I'm creating a new map object. I'm defining a subquery to pull in data from my map. And then I'm connecting to the post-GIS database. I'm adding that data source as a layer to MapNIC and then I'm rendering it to a JPEG. And this image at the top right here is partially constructed by this query I created here, so that's kind of what you can do with it. So MapNIC XML is not very pretty. It's XML, and I never want to work with it. So that's where a program called TileMill comes into play. And TileMill is a Node.js based desktop application. It's open source, but it's maintained by a company called MapBox, which does hosted mapping. And it supports a bunch of standard formats for importing data, including post-GIS and shape files. And it's built on top of MapNIC, so it's making calls to MapNIC to render the images that display in its interface. And as a result, it also can be used to generate that MapNIC XML. That's the most important thing that I use it for. So the reason why I like TileMill is because it has something called MapStyleSheets. And MapStyleSheets is a language or a market language similar to CSS or most similar to less.js. And you can change the behavior of how your maps will look in a very intuitive fashion at different zoom levels. It's a really cool application to add lots of style to your app. Or to your maps. On the back end, TileMill is using another Node.js library called Carto. And Carto will convert MapStyleSheets to MapNIC XML. And so you can call this command on the command line if you've installed it to just do this translation yourself so you don't have to even use TileMill if you don't want to, you can do this all from the command line. Another great tool for working with geodata is called QuantumGIS. It's another desktop application. It's written and see in Python. And so you can make calls to it from your Python scripts. I use this to visualize and prototype my applications. And this, I use it differently than TileMill because TileMill is, I think, better at styling your maps whereas QGIS is more like a data editor. So they both kind of can work in conjunction. But if you really just want to get some data on your map, QGIS is a great application to visualize and make sure it looks good. QGIS is a great application to do that. So now that we have some tools to work with the data, let's pretend we've created some geo queries using the Django documentation to do some fun queries with Django. And now we need to take that data and deliver it to the browser. So when I say this, I'm referring to two types of data that I typically send to the browser. And one is geography data, vector data like KML or defined shapes or KML or GeoJSON. And another one is rendered map tiles. Using MapNIC is kind of the source for that. So to create geography data, you can use any type of serializer you want. But one of my fondles really useful is one called Rust Framework GIS. And it's basically a plug-in or an application that rides on top of Django Rust Framework that defines the serializer so you can just easily turn query sets into GeoJSON output. And so this is particularly useful for, again, reading stuff from JavaScript. It's pretty easy to use and install. And then map tiling you may be familiar with. Google Maps is a good example of it as you're zooming into a mapping application. It's loading in image tiles from a server and as you zoom in the tiles kind of get more and more detailed. But there's open source solutions to do map tiling and one popular solution, Python-based solution is called TileStash. And it renders map tiles in real-time. It caches them and then it serves them up as you access them. So you can also use MapNIC as the back-end rendering engine for this and set a MapNIC style XML file to dynamically add your styles. And you can set data sources just like you can with MapNIC and the other applications. It takes a very simple URL scheme. If you run the server, you visit this URL in your browser, you'll load a single map tile. You're basically giving it a lower name, which is something you define in a configuration. A zoom level, a column and row, which corresponds to a tile location and a geo-coordinate. So here's basically what the stack looks like now that I've added. TileStash on top of MapNIC and Django Rest Framework on top of and Rest Framework GIS on top of Django. Now we have the back-end set. We need something to read it from the front-end, the JavaScript level. And there's a bunch of JavaScript client libraries that are used to actually render a slippy map application so you can zoom and interact with it in the browser. And one of those is obviously Google Maps. It's a great tool for just getting up and running, and it's used everywhere. It's got a great API, but it has some downsides in that you're kind of beholden to their API, so if it changes, you've got to update your code. It's kind of got the same look and feel across sites. There's not a lot of level or a lot of ways you can customize it to look a lot different. I'm sure there's some, but... And you also lose control of the mapping stack. Here's a quick example of code using Google Maps. And in this example, I'm defining a map object. I'm assigning the map to a div, and I'm adding a click event handler so I can click on a point on the map and it will load in, in this case, a KML file. And Google Maps automatically takes care of the map tiling for me, so that's nice that I don't have to think about that. It just pulls in map tile data as it needs it, and it superimposes your vector data on top of it. Open Layers is another good option for a JavaScript client library. It's one of the oldest open source options for map tiling, and the only downside is it's very large. It's like 700 kilobytes. They just released a new version, so maybe they helped fix some of that size problem. But in the meantime, a project called Leaflet has come into play, which I personally like. It's very small, lightweight. It's got a nice plug-in system, and it's easy to use. Here's a quick example of a Leaflet code base. I'm defining a map. I'm setting a Tile Server URL. I'm loading some data from a JSON endpoint, and then I'm adding a click handler to pull in some data as I click on a map. And you'll notice the big difference between this example and the Google Maps example is that I am setting a map tiling server URL, and in the comments above there, I have a few different map tile servers that I found that just have different types of tiles. You can include your own if you run your own map tiling server, but it gives you a little bit more customization in terms of what you see on the map. So after that, we've kind of completed our stack. In this diagram, I'm using Leaflet as the JavaScript front-end. It's pulling in map tile data and GeoJSON data, connecting with the back-end, and that's how I've architected some of the stuff. This is a pretty sophisticated topic. There's a lot to it, so there's only so much I can cover in about 25 minutes, but there's some other technologies that I just want to point out that you should Google because if you're interested in the stuff, one of them is PG Routing, which is another postgres extension for defining graphs of data and doing routing with different routing calculations. There's another front-end JavaScript application called Modest Maps. It looks similar to Leaflet to me. If you're looking for a JavaScript client, that might be something to take a look at. Grash GIS is a tool similar to QGIS. It's been around for a long time, and open source as well. Another thing to take a look at. Marble is a cool KDE project that is like a Google Earth replacement, something to kind of look at as well. That's what I have for the talk so far. I have some links to more references in the top link there. If you're interested, some just links I found useful in definitions. Also, if you're interested in seeing a working project, I have a GitHub project with some of this experimentation that I've done. It probably could use a little bit more polish, but it gets the idea across. Anyway, I appreciate your attention, and thank you very much.