Table of Contents for
Python Geospatial Development - Third Edition

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Python Geospatial Development - Third Edition by Erik Westra Published by Packt Publishing, 2016
  1. Cover
  2. Table of Contents
  3. Python Geospatial Development Third Edition
  4. Python Geospatial Development Third Edition
  5. Credits
  6. About the Author
  7. About the Reviewer
  8. www.PacktPub.com
  9. Preface
  10. What you need for this book
  11. Who this book is for
  12. Conventions
  13. Reader feedback
  14. Customer support
  15. 1. Geospatial Development Using Python
  16. Geospatial development
  17. Applications of geospatial development
  18. Recent developments
  19. Summary
  20. 2. GIS
  21. GIS data formats
  22. Working with GIS data manually
  23. Summary
  24. 3. Python Libraries for Geospatial Development
  25. Dealing with projections
  26. Analyzing and manipulating Geospatial data
  27. Visualizing geospatial data
  28. Summary
  29. 4. Sources of Geospatial Data
  30. Sources of geospatial data in raster format
  31. Sources of other types of geospatial data
  32. Choosing your geospatial data source
  33. Summary
  34. 5. Working with Geospatial Data in Python
  35. Working with geospatial data
  36. Changing datums and projections
  37. Performing geospatial calculations
  38. Converting and standardizing units of geometry and distance
  39. Exercises
  40. Summary
  41. 6. Spatial Databases
  42. Spatial indexes
  43. Introducing PostGIS
  44. Setting up a database
  45. Using PostGIS
  46. Recommended best practices
  47. Summary
  48. 7. Using Python and Mapnik to Generate Maps
  49. Creating an example map
  50. Mapnik concepts
  51. Summary
  52. 8. Working with Spatial Data
  53. Designing and building the database
  54. Downloading and importing the data
  55. Implementing the DISTAL application
  56. Using DISTAL
  57. Summary
  58. 9. Improving the DISTAL Application
  59. Dealing with the scale problem
  60. Performance
  61. Summary
  62. 10. Tools for Web-based Geospatial Development
  63. A closer look at three specific tools and techniques
  64. Summary
  65. 11. Putting It All Together – a Complete Mapping System
  66. Designing the ShapeEditor
  67. Prerequisites
  68. Setting up the database
  69. Setting up the ShapeEditor project
  70. Defining the ShapeEditor's applications
  71. Creating the shared application
  72. Defining the data models
  73. Playing with the admin system
  74. Summary
  75. 12. ShapeEditor – Importing and Exporting Shapefiles
  76. Importing shapefiles
  77. Exporting shapefiles
  78. Summary
  79. 13. ShapeEditor – Selecting and Editing Features
  80. Editing features
  81. Adding features
  82. Deleting features
  83. Deleting shapefiles
  84. Using the ShapeEditor
  85. Further improvements and enhancements
  86. Summary
  87. Index

Creating an example map

To better understand how the various parts of Mapnik work together, let's write a simple Python program to generate the map shown at the start of this chapter. This map makes use of the World Borders Dataset, which you downloaded in an earlier chapter; copy the TM_WORLD_BORDERS-0.3 shapefile directory into a convenient place, and create a new Python script in the same place. We'll call this program createExampleMap.py.

We'll start by importing the Mapnik toolkit and defining some constants the program will need:

import mapnik

MIN_LAT  = -35
MAX_LAT  = +35
MIN_LONG = -12
MAX_LONG = +50

MAP_WIDTH  = 700
MAP_HEIGHT = 800

The MIN_LAT, MAX_LAT, MIN_LONG, and MAX_LONG constants define the lat/long coordinates for the portion of the world to display on the map, while the MAP_WIDTH and MAP_HEIGHT constants define the size of the generated map image, measured in pixels. Obviously, you can change these if you want.

We're now ready to define the contents of the map. This map will have two layers, one for drawing the polygons and another for drawing the labels. We'll define a Mapnik Style object for each of these two layers. Let's start with the style for the Polygons layer:

polygonStyle = mapnik.Style()

As we discussed in the previous section, a Filter object lets you choose which particular features a rule will apply to. In this case, we want to set up two rules, one to draw Angola in dark red, and another to draw all the other countries in dark green:

rule = mapnik.Rule()
rule.filter = mapnik.Filter("[NAME] = 'Angola'")
symbol = mapnik.PolygonSymbolizer(mapnik.Color("#604040"))
rule.symbols.append(symbol)

polygonStyle.rules.append(rule)

rule = mapnik.Rule()
rule.filter = mapnik.Filter("[NAME] != 'Angola'")
symbol = mapnik.PolygonSymbolizer(mapnik.Color("#406040"))
rule.symbols.append(symbol)

polygonStyle.rules.append(rule)

Notice how we use a PolygonSymbolizer to fill each country's outline with an appropriate color and then add this symbolizer to our current rule. As we define the rules, we add them to our polygon style.

Now that we've filled the country polygons, we'll define an additional rule to draw the polygon outlines:

rule = mapnik.Rule()
symbol = mapnik.LineSymbolizer(mapnik.Color("#000000"), 0.1)
rule.symbols.append(symbol)

polygonStyle.rules.append(rule)

This is all that's required to display the country polygons on the map. Let's now go ahead and define a second Mapnik Style object for the "Labels" layer:

labelStyle = mapnik.Style()

rule = mapnik.Rule()
symbol = mapnik.TextSymbolizer(mapnik.Expression("[NAME]"),
                               "DejaVu Sans Book", 12,
                               mapnik.Color("#000000"))
rule.symbols.append(symbol)

labelStyle.rules.append(rule)

This style uses a TextSymbolizer to draw the labels onto the map. Notice that we create an Expression object to define the text to be displayed—in this case, we want to display the shapefile's NAME attribute; as you might expect, this attribute contains the name of the country.

Note

In this example, we are only using a single Mapnik style for each layer. When generating a more complex map, you will typically have a number of styles that can be applied to each layer, and styles may be shared between layers as appropriate. For this example, though, we are keeping the map definition as simple as possible.

Now that we have set up our styles, we can start to define our map's layers. Before we do this, though, we need to set up our data source:

datasource = mapnik.Shapefile(file="TM_WORLD_BORDERS-0.3/" +
                                   "TM_WORLD_BORDERS-0.3.shp")

We can then define the two layers used by our map:

polygonLayer = mapnik.Layer("Polygons")
polygonLayer.datasource = datasource
polygonLayer.styles.append("PolygonStyle")

labelLayer = mapnik.Layer("Labels")
labelLayer.datasource = datasource
labelLayer.styles.append("LabelStyle")

Note

Notice that we refer to styles by name rather than inserting the style directly. This allows us to use a single style for multiple layers. We'll add the style definitions to our map shortly.

We can now finally create our Map object. A Mapnik Map object has a width and height, a projection, a background color, a list of styles, and a list of the layers that make up the map:

map = mapnik.Map(MAP_WIDTH, MAP_HEIGHT,
               "+proj=longlat +datum=WGS84")
map.background = mapnik.Color("#8080a0")

map.append_style("PolygonStyle", polygonStyle)
map.append_style("LabelStyle", labelStyle)

map.layers.append(polygonLayer)
map.layers.append(labelLayer)

The last thing we have to do is tell Mapnik to zoom in on the desired area of the world and then render the map into an image file:

map.zoom_to_box(mapnik.Box2d(MIN_LONG, MIN_LAT,
                             MAX_LONG, MAX_LAT))
mapnik.render_to_file(map, "map.png")

If you run this program and open the resulting map.png file, you will see the map you generated:

Creating an example map

Obviously, there's a lot more that you can do with Mapnik, but this example covers the main points and should be enough to let you start generating your own maps. Make sure that you play with this example to become familiar with the way Mapnik works. Here are some things you might like to try:

  • Adjusting the MIN_LAT, MIN_LONG, MAX_LAT, and MAX_LONG constants at the start of the program to zoom in on the country where you reside
  • Changing the size of the generated image
  • Altering the map's colors
  • Adding extra rules to display the country name in different font sizes and colors based on the country's population

Tip

To do this, you'll need to define filters that look like this:

mapnik.Filter("[POP2005] > 1000000 and [POP2005] <= 2000000")