Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

PostGIS

Dane Springmeyer edited this page · 22 revisions
Clone this wiki locally

Mapnik's PluginArchitecture supports the use of different input formats.

One such plugin supports the PostGIS extension to the popular PostgreSQL database.

See also a performance tuning page: OptimizeRenderingWithPostGIS

New 0.7.0 Features

Docs TODO ->

  • Dynamic map variables
    • !bbox!
    • !scale_denominator!
  • manually setting srid,geometry_field,geometry_table
  • subquery best practices - when to set the 'subquery_extent' to true
  • controlling connection persistence

Installation

For Ubuntu, see UbuntuInstallation (specifically the package install line that includes postgresql-8.3)

On Macs, try the instructions listed on MacInstallation/Optional.

Either way, make sure that running python scons/scons.py DEBUG=y shows the following line

Checking for C library pq... yes

pq, or rather libpq, is the "C application programmer's interface to PostgreSQL". Without this library, Mapnik will not know how to talk to PostGIS / PostgreSQL, and the PostGIS plugin will neither build nor be installed.

To check if the PostGIS plugin built and was installed correctly, try the usual Python from mapnik import * on a DEBUG=y build, and look for the following debug line

registered datasource : postgis

Usage

Note:

  • Spatial tables read from PostGIS by Mapnik must have a cooresponding entry in geometry_columns.
  • Use the geometry_field parameter to specify which field to use if you have >1 geometry in the table/query (added in r769).

Python

Instantiate a datasource like:

#!python
lyr = Layer('Geometry from PostGIS')
lyr.datasource = PostGIS(host='localhost',user='postgres',password='',dbname='your_postgis_database',table='your_table')

If you want to do complex queries you can nest subselects in the table argument:

#!python
lyr = Layer('Buffered Geometry from PostGIS')
BUFFERED_TABLE = '(select ST_Buffer(geometry, 5) as geometry from %s) polygon' % ('your_postgis_table')
lyr.datasource = PostGIS(host='localhost',user='postgres',password='',dbname='your_postgis_database',table=BUFFERED_TABLE)

If you want to add something after the query (for example ORDER BY) you must use !bbox! dynamic map variable:

#!python
lyr = Layer('Order by st_lenght from PostGIS')
BUFFERED_TABLE = 'table_line where way && !bbox! ORDER BY st_LENGTH(way) DESC'
lyr.datasource = PostGIS(host='localhost',user='postgres',password='',dbname='your_postgis_database',table=BUFFERED_TABLE, srid='your_srid', geometry_field='way', extent='your_extent')

XML

If you are using XML mapfiles to style your data, then using a PostGIS datasource (with a sub-select in this case) looks like:

  • Note: if you use a sub-select that changes the extents of your features, make sure to use estimate_extent=false otherwise Mapnik will return no features. Otherwise you don't need to use the estimate_extent or extent parameters at all.

    !xml

    countries_style_label postgis localhost geodjango_geographic_admin postgres
    (select ST_Buffer(ST_Centroid(geometry),2) as geometry, name from world_worldborders) as world false -180,-90,180,89.99

Note: If you use a custom projection, you might need to change the extent parameters to the area for which the projection is defined. For example, the Dutch grid (EPSG:28992) is only defined around the Netherlands. It does not make sense to try to project South America onto it. You need to change the extent parameter to something like this:

#!xml
      <Parameter name="extent">3.09582088671,50.6680811311,7.41350097346,53.6310799196</Parameter>

If you don't do this, you might not see data from this data source at all, even if it does not contain data outside of the valid region. Also note that you always specify the extents in the coordinates of the source system.

C++

Plugin datasource initialization example code can be found on PluginArchitecture.

A PostGIS datasource may be created as follows:

#!C
{
    parameters p;
    p["type"]="postgis";
    p["host"]=database_hostname;
    p["port"]=5432;
    p["dbname"]="gis";
    p["user"]=your_username;
    p["password"]="";

    Layer lyr("Roads");
    set_datasource(datasource_cache::instance()->create(p));
    lyr.add_style("roads");
    m.addLayer(lyr);
}

For other PostGIS parameters, see the postgis_datasource constructor in postgis.cpp:L57

TODO -- more PostGIS query usage

Further References

Using Mapnik and PostGIS with OSM

Something went wrong with that request. Please try again.