Batch importing shapefiles into PostGIS

Batch importing data into PostGIS is a topic I have covered previously in my article on importing CDSM (Chief Directorate: Surveys and Mapping) data into postgis. However its a popular question I get asked so today I am going to take another look at the problem. In particular the client has a directory heirachy of zipped shapefiles divided by regions in Africa. The shapefiles use a common naming convention which makes things easier. The convention is basically something like:

<number><region_name>/<region_abbreviation>_master/<region_abbreviation>_<feature_type>_<feature name>.zip

For example:

02 Mozambique Malawi/moz_master/moz_a_parks.zip

When unzipped the shapefiles are consistently named across regions e.g.:

moz_a_parks.shp
moz_a_parks.shx
moz_a_parks.dbf
moz_a_parks.sbn
moz_a_parks.sbx

From that we can define a few rules:

  • Recurse the top level directory looking for all zip files
  • Get the base name of the zip file without its extension (e.g. moz_a_parks)
  • Strip the region off the base name – this will give us the standard feature class name / table name used across all regions for that feature type.
  • Extract the zip file to /tmp
  • If the feature class / table does not exist in PostGIS, import it with the -c (create) option
  • Otherwise import it with the -a (append) option

So here is the little script I wrote that achieves this.

#!/bin/bash
DATABASE=foo
IFS="$(echo -e '\n\r')";
FILES=$(find -name "*.zip");
for FILE in $FILES
do
  BASE=$(basename $FILE .zip)
  TABLE=$( echo $BASE | sed 's/^[a-z]*_//g')
  # double check the extracted files have been cleaned up or zip will moan
  rm /tmp/${BASE}.*
  echo "$BASE to $TABLE"
  unzip -d /tmp $FILE
  MATCH=$(echo "\d" | psql ${DATABASE} | grep -o "${TABLE}")
  if [ "$MATCH" ]
  then
    # Append to the exisitng table
    echo "Appending to ${TABLE}"
    shp2pgsql -s 4326 -I -S -a -W UTF-8 "/tmp/${BASE}.shp" $TABLE | psql $DATABASE
  else
    # Create the table
    echo "Creating $TABLE"
    shp2pgsql -s 4326 -I -S -c -W UTF-8 "/tmp/${BASE}.shp" $TABLE | psql $DATABASE
  fi
  # clean up
  rm /tmp/${BASE}.*
done

If your shapefiles are already unzipped into a directory structure, you could easily modify the script above to find ‘.shp’ files rather than zip files and leave out hte unzipping , cleaning up steps.

Once you have run the scripts, open your favourite PostGIS client (I use psql) and take a look at the tables created there. If all looks good you should be able to start browsing the datasets with QGIS or publishing them with Mapserver!

pixelstats trackingpixel

Comments

  1. jatorre says:

    I love you bash tutorials. Can I ask you to post much more batch tutorials? How much I would like you seeing you using EC2 for geo data processing, you my batch guru!

  2. Tim Sutton says:

    Hi Javi!

    Sure I will post when I do something useful with it :-)

    One day when South Africa actually has a decent internet I will start to play on the cloud! :-)

    Regards

    Tim

  3. [...] Импорт большого количества SHP-файлов в PostGIS. [...]

  4. geographika says:

    Also check out http://openlayerer.appspot.com/ if you want to create a slim OpenLayers.js online.

    I used the JSTools build scripts with MapFish, but using Windows. This post may also be of use to Windows users – http://geographika.co.uk/minifying-the-mapfish-client-on-windows

Submit a Comment

You must be logged in to post a comment.