Book Image

Python Geospatial Analysis Essentials

By : Erik Westra
Book Image

Python Geospatial Analysis Essentials

By: Erik Westra

Overview of this book

Table of Contents (13 chapters)
Python Geospatial Analysis Essentials
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

A program to identify neighboring countries


For our first real geospatial analysis program, we are going to write a Python script that identifies neighboring countries. The basic concept is to extract the polygon or multipolygon for each country and see which other countries each polygon or multipolygon touches. For each country, we will display a list of other countries that border that country.

Let's start by creating the Python script. Create a new file named borderingCountries.py and place it in the same directory as the TM_WORLD_BORDERS-0.3.shp shapefile you downloaded earlier. Then enter the following into this file:

import osgeo.ogr
import shapely.wkt

def main():
    shapefile = osgeo.ogr.Open("TM_WORLD_BORDERS-0.3.shp")
    layer = shapefile.GetLayer(0)

    countries = {} # Maps country name to Shapely geometry.

    for i in range(layer.GetFeatureCount()):
        feature = layer.GetFeature(i)
        country = feature.GetField("NAME")
        outline = shapely.wkt.loads(feature.GetGeometryRef().ExportToWkt())

        countries[country] = outline

    print "Loaded %d countries" % len(countries)

if __name__ == "__main__":
    main()

So far, this is pretty straightforward. We are using the techniques we learned earlier to read the contents of the shapefile into memory and converting each country's geometry into a Shapely object. The results are stored in the countries dictionary. Finally, notice that we've placed the program logic into a function called main()—this is good practice as it lets us use a return statement to handle errors.

Now run your program just to make sure it works:

$ python borderingCountries.py
Loaded 246 countries

Our next task is to identify the bordering countries. Our basic logic will be to iterate through each country and then find the other countries that border this one. Here is the relevant code, which you should add to the end of your main() function:

    for country in sorted(countries.keys()):
        outline = countries[country]

        for other_country in sorted(countries.keys()):

            if country == other_country: continue

            other_outline = countries[other_country]

            if outline.touches(other_outline):

                print "%s borders %s" % (country, other_country)

As you can see, we use the touches() method to check if the two countries' geometries are touching.

Running this program will now show you the countries that border each other:

$ python borderingCountries.py
Loaded 246 countries
Afghanistan borders Tajikistan
Afghanistan borders Uzbekistan
Albania borders Montenegro
Albania borders Serbia
Albania borders The former Yugoslav Republic of Macedonia
Algeria borders Libyan Arab Jamahiriya
Algeria borders Mali
Algeria borders Morocco
Algeria borders Niger
Algeria borders Western Sahara
Angola borders Democratic Republic of the Congo
Argentina borders Bolivia
...

Congratulations! You have written a simple Python program to analyze country outlines. Of course, there is a lot that could be done to improve and extend this program. For example:

  • You could add command-line arguments to let the user specify the name of the shapefile and which attribute to use to display the country name.

  • You could add error checking to handle invalid and non-existent shapefiles.

  • You could add error checking to handle invalid geometries.

  • You could use a spatial database to speed up the process. The program currently takes about a minute to complete, but using a spatial database would speed that up dramatically. If you are dealing with a large amount of spatial data, properly indexed databases are absolutely critical or your program might take weeks to run.

We will look at all these things later in the book.