Processing Open Street Map Data with Python and PostgreSQL

Getting started with Open Street Map data can be an intimidating process. With so many data formats to choose from, how does one pick the correct one and get started? In this talk, I guide listeners through one possible way to organise and process this data using PostgreSQL and Python.

The talk starts off with an introduction of OSM data and how it's structured. From there, we learn how to import this data to a PostgreSQL database and learn about how this data is structured with the PostGIS extension. We'll go over some amazing open source tools that give us the ability to do this, specifically osmium and osm2pgsql.

Afterwards, I cover how to structure a Python project for analysing this data and show how this project structure can enable us to easily repeat and share our analysis projects. To close out the talk, I introduce an example use case.

This session took place in track Data Handling and was classified suitable for some domain / some python by the speaker.

Transcript (auto)

Auto-generated from the recording utilizing Open-Source AI. Speaker labels (Speaker 1, Speaker 2) reflect diarization, not identity. Timestamps refer to the recording.

Speaker 1 [00:04]

Hi, and welcome, everybody. My name is Travis, and like an introduction said, I'm going to be talking about OpenStreetMap data. Just a really quick show of hands, who out here has heard of OpenStreetMap? Great. So OpenStreetMap is a very popular project, and I'm really happy that you're here to learn about it with me today. Cool. So what exactly are we going to cover? Well, first off, we're going to talk about OpenStreetMap, kind of the community surrounding it, and get into what the data types are, how it's structured, and how you can kind of filter it and search through it. After this, we're going to talk about PostgresQL and how to work with geographic data in PostgresQL, specifically focusing on the PostGIS plugin. And then we'll talk about how you get OpenStreetMap data into Postgres. And at the very end of the talk, we're going to talk about how you structure analysis projects with Python. And that'll be the most fun part of the talk because obviously we're at PyCon conference. So, cool. So, why am I giving this presentation? So, the idea for this talk started last year when I was doing research for my master thesis project. And in my master thesis project, I was doing an analysis of walkability in the city of Kiel, Germany. And to do this, I used a lot of OSM data. And to kind of help keep myself structured and organized, I needed a process. I needed kind of a way to keep the madness in order. And basically this is what I came up with and I'm really happy to share with you today and just a little bit more about who I am and where you can find me so first off I have a website Travis Hathaway calm I just want to let everybody know that you can go there after this talk to kind of see a blog article that is basically the mega tutorial that is this speech so everything I say here you'll be able to find there you can also find the example code that I use in this presentation on GitHub. You can find all the other stuff I do on GitHub. And if you want to get in touch with me, you can send me a message on LinkedIn. And then finally, if you want to hear all the kind of weird, bad music I write and make, you can go to SoundCloud. So I always like to get an opportunity to present that. And then who am I? Yeah, above all, I'm a Python programmer, but also, too, I'm a GIS enthusiast. I've never actually worked as a professional kind of GIS practitioner, so to say. I've always been a software engineer, but I've always really done this as a hobby. I'm also a social scientist. I actually just recently completed a master's degree in, the program was called Sustainability, Society, and the Environment. And it was really fun to kind of use my software skills to figure out how to kind of tackle social issues. And then last, I'm a guitarist and musician. Very amateur though. Cool. And so who are you? And who is this talk for? Basically, this talk is for anybody who has an interest in both Python, PostgreSQL, GIS, and especially you enjoy messing around with data. The OpenStreetMap database is enormous, very, very big, and there's lots of really cool stuff going on there, and it's growing all the time. So let's kind of dive headfirst into OpenStreetMap, talk about what it is. So what is OpenStreetMap? is actually a huge community. And not only is it a community, but it's a community of communities. So all around the world you have local chapters that are all dedicated to basically mapping out their communities and making this data open source and freely available to everyone to use. So the contributors include individuals, just like you and I, but also public and private organizations, as well as local, state, and national governments. And if you go to the Wikipedia page, the list of contributors is actually mind-blowing. It's so big. Okay. So enough about the project itself. Let's get into the data types. So in OSM, OpenStreetMap, there are primarily three different data types. We have nodes, ways, and relations. Let's get into each. So first off, a node, think of a node as a point. It's a point with a geographical space that has latitude, longitude, and NOID. And so some common examples of what these things are include things like park benches, wastebaskets, toilets, anything that's just a simple XY coordinate on a map. And then the next data type, a little bit more complex, we moved from nodes to ways. So a way is actually just a collection of nodes, and they come in three different flavors. So the first one is an open way, and an open way, you can think of it as just a line. And so these include things like streets and rivers and streams. And then we have two more different types of ways. And these are closed ways and areas. So a closed way is basically a line, but it starts where it stops, right? And so these are things like roundabouts fall in this category. And then the second thing we have are areas. And so these are what you would see on the map as basically a polygon shape. And these include parks, natural areas, as well as political boundaries. And as well as things like buildings, too. And this would be a good kind of way, a good point in the presentation to interject this statistic is that OpenStreetMap is actually the largest database in the entire world of building footprints. So that's pretty cool. And finally, we have what's known as a relation. And so relations basically provide a way to arbitrarily nest and kind of relate the first two types of data to each other. So with relations, you can group points, nodes with each other. You can also group ways. But also, too, some interesting kind of use cases emerge. So anything, any polygon that has a circle in it, so, for example, a lake with an island or a building footprint that has a little courtyard in the middle, that's going to be a relation because it's a polygon and then a closed way. And then next thing you have are university campuses. think any sort of, so a university campus isn't necessarily just one building, but it's multiple buildings. So in order to encapsulate that, we use a relation. And then the other thing too is we're going to put bus routes there. And so these are open ways, so these are all like lines that are grouped together to express a single thing. And then finally, we've got all this great data, but how do we categorize it and how How do we search through it? OpenStreetMap has a system of tagging. At its heart, it is a simple key value store. We can use this to categorize nodes, ways, and relations. From the OpenStreetMap wiki, it says you are free to create any tag you like. It is supposed to be really, really versatile. Anybody can submit stuff that they want. But the thing is is that if you try to go all willy-nilly and create whatever you want, you might run into some, you know, because there's other people that use it, too. And the community has informal standards for this. And so if you're using a tag but there's clearly a better alternative available that more people are using, then you're going to be gently kind of pushed into using it in that direction. But with that being said, if you are able able to find a new tag and this hasn't been used before and then all of a sudden there's a big demand for it and your tag catches on and people start using it, this is a way for it to informally become a standard. The last thing I want to mention about tags is that, yes, it has this informal way of being adopted and being adopted in the community, but there's also a formal process to making changes with tags, and so anybody can go on the OpenStreetMap wiki and they can submit a proposal and then these proposals go through various stages including votes and all that kind of stuff before it's officially adopted. Here are some example tags. The first one is called amenity. Amenity is really popular because it includes all the kind of things that are typically useful to people or places that people want to go. Some example values here are going to be cinema, post box, town haul and wastebaskets because everybody needs wastebaskets and then the second thing we have is a is a tag called land use and land use might be more interesting to people doing environmental research because it's gonna have values such as commercial industrial residential but it's also gonna have things such as farmland and forests and so you can do some really interesting environmental analysis in OpenStreetMap with that tag alone all All right, so just to explain all this data, sounds great. How do I get my hands on it? Well, OpenStreetMap has a system of mirrors available. To see the full list of mirrors, you can go to OpenStreetMap.org. And they have basically a big list of a bunch of different types of mirrors. My personal recommendation, though, is it's a mirror called Geofabrique. And they have the best organization of this data. Basically, when you go to the page, presented with a list of continents and you can kind of drill down and go deeper and deeper and deeper. It's really nice. But the other thing, too, is that sometimes this website is down, so apparently these guys need some love. Let's look at supporting them because they actually provide a really, really great service. So, yeah, really happy for them. And then once you get the data and you download it, there's actually a specific type of binary format that OSM uses called the PBF. Before there were several other formats such as XML, you can actually even download these files as shape files, but as far as community standards goes and interoperability with all the different tool sets out there, this PBF format is the recommended one, and it's going to be the fastest to process. Now we've covered the basics of OpenStreetMap data, how do we actually work with this in PostgreSQL. Before we do that, what I want to do is talk about, well, what is actually even geospatial in PostgreSQL anyway? Like many things in the open source community, the PostGIS plugin that I'm going to talk about was kind of a confluence of a lot of good ideas. PostGIS started back in about 2001, and one of the key things that made PostGIS possible was Postgres' extension system. Because extensions were so easy to create, the initial PostGIS plugin was actually written in under a month and just included just basic geographic data types. And so they kept chugging along, but the problem was that although they had these awesome data types now for PostgreSQL, they had no way to kind of perform any sort of geospatial analysis. And so this is where projects like the Open Geospatial Consortium come in, and also another open source library called libgeos, and with the simple features for SQL standard defined, and also too the libgeos, basically it's a C++ library providing all of the algorithms for implementing these kind of geospatial analysis. And so when I say that, these are things like, you know, if you have a polygon, like how do you figure out how many, all the points inside this polygon? And so because of these two other organizations and projects, these were able to be easily adapted and kind of incorporated into PostGIS, and then later on, once they had that, then we had basically a full suite of geospatial operations in PostGIS. The other thing I want to mention too is that PostGIS adds the spatial data types, it has the spatial processing functions, and it also has basically spatial indexes as well. Cool. And so what do these data types actually look like in PostgreSQL? Well, we have a root geometry object, and then below that we have points, line strings, and polygons. And then on the same level we have something called a geometry collection, and below that we have multipoint, multiline, and multipolygon. And so those are basically all the data types. There's There's some other geography stuff, too, but I'm not going to get into that in this presentation. How do these data types then map to the data types that we just saw with OpenStreetMap? Luckily, it's pretty simple. It's basically a one-to-one mapping. For nodes that go through a point, open ways and closed ways are represented as line strings. Areas are represented as polygons. All these relations I'm talking about can be represented as multi-polygon, multi-line string. That's pretty simple. Now you might be asking yourself, well, how do I write a geospatial query? Sorry. We don't have enough time for that, but what I'm going to say to you, because that's basically a whole presentation in itself, what I'm going to say to you is go to PostGIS.net, check out the introduction. It's amazing. It's quite literally like a 30-chapter introduction, and they work with some U.S. census data, so it's actually you're working with real data, learning how to run these PostGIS queries. I would highly recommend checking that out. And again, like I said, if you go to my website and go to my blog, you will find a link there. And on my blog article, I actually do give a little bit of a rough intro to writing spatial queries as well. But that's when the real fun starts. All right. So now that we know kind of, okay, a little bit more about spatial types in PostGIS and how it relates with OSM, now we want to know how do we actually get this data into our database. So there's a variety of tools out there, and I'm going to introduce two of them to you. The first one is a tool called Osmium. And this is a command line tool with lots of functions. It's basically a Swiss army knife of OSM data. And with this tool, you can do diffs, extracts, merge, and filters, all using this PBF format that they have. And so what does an example command look like? So this is an Osmium command that filters all of the... It basically filters all the amenities out of this large PBF file, this Germany latest. Just to give you an idea of how large this file is when you download it, the OpenStreetMap data file for Germany right now is about 3.6 gigabytes, so it's a pretty large file. The second tool that you can use to get this stuff into PostgreSQL is something called osm2pg-sql. This is a command line tool that you can use to import OSM data, but it also has two different modes of operation, including creating and updating. Then as of version 1.5, it supports complex rules via LUIS scripts that we're going to talk about a little bit later. Here's what an example use of this function looks like. You just tell it which database you want the data to be imported to, and then you also give it a PBF file. When you import it, you're going to get this list of default tables. It's going to be line, so this planet OSM line, planet OSM point, and then planet OSM polygon and roads and so this is really cool for if you just want to kind of dig in and do some exploratory data analysis and I definitely recommend this at first but as you kind of start working on a project the names of these tables are very semantic they don't really tell you what's in there it's just a line point polygons, so it might be really hard to categorize and make your table schema nice, which is really important if you're going to start any project with a database. It's always nice to have a really nice, clean-looking database schema, which isn't always the case, as I've seen in many projects. How do we solve this problem? With OSM to PGSQL, there is an ability to have a flexible input. This is what I was talking about earlier with the Lua scripts. In order to do this, you basically specify output flex, and then you use the style flag to point it to your Lua script. I'm going to show you an example of what a Lua script looks like. Actually, a quick show of hands, how many people have ever done any programming at all in Lua. Awesome. That's cool. I think you should know that, but Lua is a really simple language. A lot of times you'll find it embedded in other things. I believe it's also available in Redis, but don't hold me on that. Let's get back to the slide at hand. In order to define your tables, you're going to create a variable called tables. Then below you just define what each one of those tables is going to look like. So the first one we'll define is an amenity polygon, and then we give it the name here, and then what we do is we kind of map some of the values to Postgres values. And so what we're going to do is we're going to store the type of amenity, we're going to store all the other tags associated with this, and actually that's a good point to mention too. So nodes, ways, and relations, they can have multiple tags. So they can be quite rich and quite detailed. Yeah, and so then finally what we'll do is we're going to define a geometry column there, and then give a default projection. And then another thing I'll mention too is when you're importing OSM data with the tool, by default it's using this 3857, which gives you your coordinate system in meters rather than degrees, like latitude and longitude, which can be actually a lot better. At first, you kind of look at the data and you think, okay, these huge numbers, I don't know what they mean. But it's really nice when you can use meters because then you can actually more easily transfer it to kind of real-world measurements such as kilometers. So, yeah, because the conversion from meters to kilometers is easier than degrees to kilometers. So, cool. And then below, we're going to define then a second table for our points. and doing basically the same thing. And then one thing I want to note, too, when you use the flex output, you can't store points and polygons beside each other. They have to kind of go to their own separate tables. So, cool. All right. And then, so, and usually in the upper part, you're going to kind of define what you want your tables to look like, and then below, you have these kind of hook functions where you can basically just define what you want when you're going to be importing something. So here I've defined a hook function for processing a node, and it does a really simple thing. It's just going to say, hey, if this objects, tags, amenities thing is not null, then we want you to go ahead and import it. But because you can use if statements here, I mean, these can get as complicated as you'd like. Yeah, and I'm going to link later to a really great Git repo where someone's built a lot of really amazing Lua examples that you can use. You don't have to start from zero if you don't want to write that much Lua. After you've basically done this import, you can see that our table schema looks a bit better now. Now we have all of our data organized by the type of data that they are. We have amenity points and amenity polygons. Now we're getting into the best part of the talk because it's the Python part of the talk. Very cool. Organizing your projects with Python. How do we even go about doing something like that? Let's go ahead and organize this as if we're completing a task. You've just been given a task and you won a contract. You bid. There are all kinds of bidders, but you've eventually won this contract. It's a lucrative contract, too. You're getting millions of dollars for this. Or millions of euros. It's going to be really cool. It's a contract with Trash cans united they're a trash can advocacy group and they want to do trash can research in germany and you're going to be their eyes and ears on the ground so for this project what they require is they want to know the statistics for all the trash cans and the 10 largest cities in germany um and they also want to know like what's the number of trash cans over time you know they They're probably going to want to come back to you every year. And you're thinking to yourself, you're thinking, wow, this is great. This is a contract that I'm going to be able to get money for every year. Awesome. And then the other thing they want to do is they say, yeah, well, Travis, you know, at first we're going to want trash can info for the top, you know, 10 cities. But, you know, over time, this could grow. Maybe we even build a trash can dashboard on our website. And so all these things, and your mouth's getting wet at this point because you're like, oh, I mean, you just see dollar signs in your eyes because you're really, really ready to work on this. And for some reason, now you love trash cans. So let's get into it. But before we get started with this, right, let's see what this data pipeline kind of looks like. And so for this data pipeline specifically, we're going to want to initially get some data from Geofabrique. and then we're gonna store that in an initial PDF file and then afterwards what we'll do is we're gonna extract all the cities that we care about so the top 10 and I'm in Germany and then we're gonna basically write that to our own kind of project data file and then and at the end we're gonna want to import it into a Postgres database and then from there we can write all the kind of reports that we're gonna need and output this as diagrams and then send it to trash cans united cool but the uh the thing is though is that i i just i don't know how i'm gonna go about organizing this i i think maybe well i i could write a web application but that seems a little overkill you know it's i don't even i don't know if i want to go there yet and then so you're thinking now like how how could i possibly do it you what what's that obi-wan use the CLI? Yeah, that makes sense because what did we just see? We just saw two awesome, you know, CLI programs, Osmium and OSM2PG SQL. Why not write our own and throw that in the mix? That sounds like a great idea. But, and I hope this doesn't describe any of you here, but maybe some of you hear the word CLI and you think, you think this, right? No? Okay. Let me go ahead and just kind of assuade your concerns, right? Why are CLIs great? All right. So why is writing a CLI a good idea? So this enables kind of rapid development, fast feedback cycles, right? So you're writing it and you can test it, write it, run it, write it, run it. And when you're doing that, it's really important because then you can kind of see your changes over time and just have a really fast feedback cycle so that you can develop quite quickly. The other thing, too, is that these tools can be integrated with other tools, right? They're composable. So the other tools we just saw, Osmium and OSM2PG SQL, they can be included as part of a data pipeline like we just saw. The other thing, too, is that recently, and I'm sure a lot of you know this, but the CLI out there, the ecosystem for Python is amazing. And it's also amazing across a bunch of other libraries. So my personal favorites in this realm are Qlik and Rich. Qlik is great because it can help you structure your CLI programs. And Rich can help make them beautiful. So there's a lot of really good tools out there. And, yeah, that's how we're going to do it. And so our CLI program is going to be called, in kind of the OSM spirit, everything should begin, all CLI tools should begin with OSM. So it's going to be called OSM proj, which stands for OSM project management. And then specifically what we're going to do is we're going to have an initial command called OSM proj prepare. So this is going to do the downloading and extraction process. And then we're going to have OSM proj report. And that's going to do our reporting process. And the cool thing is because OSM to PG SQL is already such an amazing tool, it's going to handle the importing for us. Really excited about that. When we write the program, what does the actual file structure layout look like? This is just one example. This is my personal preference for how I like to do this stuff. We're going to have a top-level folder called osm-proj, and then below that, we're going to have a folder called commands. Whenever I'm writing command line tools that have these kind of subcommands here, like prepare and report, I'm always going to basically dedicate separate files to them. It makes the project really easy and nice and orderly, and you're able to find everything quite quickly. Then we move further down, basically we're going to have this CLI, so this is going to be where the entry point to our CLI program lives. Finally, I'm going to have separate modules for doing things with databases and separate modules for doing things with HTTP. I like to organize my modules in terms of services. For example, if you go to the repository website, you're going to also see other things such as report or chart or cache. Every kind of new service has its own separate module. Finally, for packaging and doing everything, I'm using Poetry right now. That config is going to live in a PyProject toml. And then finally, every good project needs an even better readme. So always include that readme. And so now we're going to get into the nitty gritty of what these commands actually look like. So for osm-prepare, we're going to basically it's going to be a command that accepts a config. And inside this config is going to be all the cities that we want to extract. And then this second argument here is this Europe-Germany. And this kind of roughly maps to the way these things are kind of passed on Geofabrik. So that's going to enable us to download, store that quite easily. And then finally, we're going to have an output file. So it's going to be our project.data. And so inside of this config file is going to live. It's a JSON file. It's going to hold the extracts. And this is also the same format that the Osmium tool accepts. And also I should mention right now that underneath the covers, prepare is actually calling basically two Osmium commands. We're calling extract and merge. So we're basically downloading everything. And then we extract all the cities that we want. And at the very end, we merge everything together to get that project data. And also too, and then the really cool thing is that you can write these Python programs and use subprocess. And in my opinion, writing a Python program like this is much better than writing a bash script. That's just my personal opinion, and I think maybe some of you would agree. Cool. Now let's talk about what does the reporting look like. For the reporting, we're going to have a couple of different things going on. First, we want to define the top cities, and we'll define that as a shell variable, but really what we're doing is just passing it in later as an argument. This is a nice little shorthand to do that and then we have the same config and in this config we're gonna hold things like a database connection so we don't have to pass in everything on the command line so that's another nice thing to do and then this is kind of meat and potatoes of this specific report so the reports are gonna hold these kind of sub reports and the this is called amenity city and then it accepts two different types of arguments it's gonna accept the city's argument and then also the amenity that you want to measure and for us it's gonna be wastebasket because we're doing trashcan research and then finally we have an output type right and so this output type is gonna be a chart and then what this does is it's gonna use the plotly library to write us a nice-looking HTML chart but the cool thing is I'll talk about this later is that with this output type right you can you can throw anything you wanted it right you can do a terminal output if it's gonna be used for a web map you can do a GeoJSON output so this is really cool and when you kind of start thinking about your programs like this, you can start thinking modularly and how you want to extend it. When you want to add a new output type there, it's as easy as just adding a new type. Actually, wait. I hope no one saw that. Actually, before I show that next graph, does anyone who thinks, and maybe everyone saw it, but who thinks is the city with the most trash cans in Germany. Yeah? Anyone know? Okay. I'll go ahead and show you. Basically, the number one city in Germany is Stuttgart, closely followed by München, and then Berlin, and then Köln. Also, too, I want to let you know that this is the amenity per square kilometer, so this is kind of an imperfect measurement, right? But it's, yeah. Basically, Stuttgart has 11.93, basically 12 trash cans per square kilometer, so that's how you can read that. And yeah, it's fun. This was just kind of thrown together quite quickly. Moving on and getting an actual better analysis here, I think that you would want to bring in population density. That would be another good thing to do. Yeah. But this is just super, super simple. And this is actually, so population density, I'd have to bring another data set, But this is just using all the data that's available in OpenStreetMaps. And then, like I said before, when you can utilize different outputs, especially using something like Rich, you can generate these nice, beautiful tables on the terminal, so that's really cool. And then you can add more data, right? So the actual number. So if we looked at total numbers, Berlin wins by far. It's got 7,489 trash cans, which is a lot, but it's also the biggest city. But the other thing, too, is when we're looking at this data as well, right, this is a good point to mention this about kind of OSM data, is that just because, you know, what you see here, you have to remember, because it's community-contributed data, so if we look at Leipzig, okay, we could say, yeah, oh, man, there's barely any trash cans in Leipzig. You know, they only have, like, two per square kilometers. But the thing is, is maybe they haven't been tracking them as well as Stuttgart. So just remember, when you go digging into OSM, you need to also be verifying by either doing, like, kind of using in-situ measurements where you're basically looking on the ground or verifying it with another data set or even trying to see, okay, who is actually contributing the data, like the trash can data. and all that you should be able to do on their website where you can actually see who contributed to that. And if you go to OpenStreetMap.org, you can click on individual features and see who the actual contributor was. Cool. And so, yeah, one of the last things I wanted to talk about was kind of sharing your work with others. And this is where writing CLIs and kind of thinking in this way can really help when you want others to either help out or extend the project that you've done. So I highly encourage people to, from the outset, right, think about how they're going to package and share their work with others. And one of the really great ways is to use kind of like a tool like Poetry in order to help you build Python packages and put them on PyPI if you'd like to make it public and open source, but even if you don't want to make it public or open source and just have it be private, tools like this can be really, really useful for getting people started. This is one of the last slides I want to show. This is why you would use this method. Like our project requirements said earlier, is They gave us initial specifications, but they kind of had this MVP, the minimum viable product they wanted. But then what they wanted to do is scale up, maybe add new reports, maybe add different kinds of reports, add new cities. So this method would be great if you're dealing with adapting project specifications. That is the whole idea about good software design. You build software to be flexible to changing circumstances. That is a really cool way to build your analysis projects too. The other thing is that you can use this method if you want to run this repeatedly. You are going to need to run this on a server or in a Docker container or maybe in some sort of GitHub Action or something like that. You want to have robots do this for you. But the cool thing is when you write CLIs, right, CLIs are friendly to robots, but they're also friendly to humans, too, which is cool. And like I said before, it helps you to share your code. And furthermore, and this is the last point I'll talk about, is when you write programs in this way, it can kind of help instill best practices in software design. So for me personally, when I first started my analysis project last year, it was initially done using kind of JupyterLab and Jupyter Notebooks. And while this is really great for exploratory data analysis, and if I just kind of want a proof of concept, just kind of do something really quick, I'll go to that. but I also had the problem where the Jupiter notebooks eventually got so big that I just kind of I was super confused by them and they don't have all the nice things that you get from an IDE right like code linting and those kinds of things so what I what I now my workflows what I try to do is that yeah Jupiter notebooks an amazing place just to kind of sketch things out but as soon as I have a really clear idea of what I want the project to be, I jump right back into an IDE and I start planning my projects in this way. But that's my own personal experience. And I know there's going to be some great talks on Jupyter, and I'm actually really looking forward to them, too. So cool, cool. I'm not trying to dog on Jupyter, but for my personal workflow, that's usually what I'm doing. Exploratory data analysis there, and then when I have everything kind of cemented, I'm moving to an IDE to really plan everything out. All right, so these are the resources that you can go check out. Like I said, my blog site is going to have them there, but then there's also some further resources available below, and then, yeah, I think I briefly mentioned it, but really this PGE OSM project, PGE OSM Flex, has tons and tons of great Lua examples. Their whole idea is that they really want to kind of create an analysis-ready database, So even more so than these Lua-like scripts, they also have, like, a Docker image that you can use to kind of quickly just get a database and begin connecting to it and doing analysis. So I really would recommend checking that project out. And then, like I said before, the introduction to PostGIS is really great, too. And then the other thing, too, is this TagInfo website that I may have briefly mentioned. But tag info is cool because you can look at all the different tags in OpenStreetMap But then you can see how many are used and so you can start to get an idea Okay, how popular is this tag and how how widespread is its use? So cool, and I believe That does it so thank everybody for listening my thoughts So, thanks, Travis, for this interesting talk. And unfortunately, given the delay on the opening session, we don't have time for the questions, but you can ask your question directly to Travis, I think, here in the conference after the talk. And thanks for being here and enjoy the next talk in the conference. Thank you, everybody. Thank you.

Travis Hathaway

About — in the speaker's own words

I am originally from the United States (Portland, Oregon) but now live in Kiel, Germany. I recently completed a masters program at Kiel University called, "Sustainability, Society and the Environment" where I specifically focused on sustainable mobility in cities. Before that, I worked as a software engineer for several companies and have been programming in Python for close to 10 years now. Additionally, I am an amateur musician and started playing guitar at the age of 15.

Social card for talk: Processing Open Street Map Data with Python and PostgreSQL