CGDI Postal Code Lookup Service 2.0.0 documentation

Canadian Geospatial Data Infrastructure
Author:Tom Kralidis
Contact:tom.kralidis at ec.gc.ca
Release:2.0.0
Date:$Date: 2010-06-29 09:23:23 -0400 (Tue, 29 Jun 2010) $

Introduction

The CGDI Postal Code Lookup Service provides an XML-encoded web service, which returns geometries for known forward sortation area (FSA) postal codes.

The service provides point geometries for FSAs as per point data obtained from Statistics Canada. The service returns record(s) for matching FSAs with point geometry, encoded as GML.

Below is a diagram of how the service derives feature geometry for postal code records.

CGDI Postal Code Service Request / Response Model

Installation

The CGDI Postal Code Lookup Service software can be easily installed on any OS with an existing HTTP server environment (such as Apache httpd).

Requirements

The software requires a Python interpreter. Your HTTP server must be able to support Python CGI scripts.

Install

Installation is easy; unpack the source code into a web accessible directory:

$ tar zxf postalcode-2.0.0.tar.gz

Configuration

Edit the following variables in default.cfg:

[server]

  • datapath: the full path path to the csv file (data/fsa.csv)
  • url: the URL of the resulting service
  • lang: the ISO 639-2 language and country code of the service (e.g. en-CA)
  • encoding: the content type encoding (e.g. ISO-8859-1)

[service]

  • title: the title of the service
  • abstract: some descriptive text about the service
  • keywords: a comma-seperated keyword list of keywords about the service
  • fees: fees associated with the service
  • accessconstraints: access constraints associated with the service

[provider]

  • name: the organization name of the provider
  • url: the URL to more information about the organization
  • individualname: the contact name of the provider contact
  • positionname: the position title of the provider contact
  • phone: the phone number of the provider contact
  • fax: the facsimile number of the provider contact
  • address: the address of the provider contact
  • city: the city of the provider contact
  • administrativearea: the province or territory of the provider contact
  • postalcode: the postal code of the provider contact
  • country: the country of the provider contact
  • email: the email address of the provider contact
  • hoursofservice: the hours of service to contact the provider
  • contactinstructions: the how to contact the provider contact
  • role: the role of the provider contact

Testing

At this point, you should be able to run requests on the command line:

$ ./postalcode.cgi "version=2.0.0&request=GetCapabilities"
.. lots of XML output
$ ./postalcode.cgi "version=2.0.0&request=DescribePostalCode"
.. lots of XML output
$ ./postalcode.cgi "version=2.0.0&request=GetPostalCode&code=m9c"
.. lots of XML output

Service Location

The service will be located at http://host/path/to/postalcode/postalcode.cgi This URL must match the server.url parameter in default.cfg.

HTTP Request Rules

The CGDI Postal Code Lookup Service accepts both HTTP GET and HTTP POST. Keyword parameters are case insensitive, however value parameters are case sensitive unless otherwise specified.

Operations

The service supports three (3) operations:

  • GetCapabilities
  • DescribePostalCode
  • GetPostalCode

GetCapabilities

The purpose of the GetCapabilities operation is to provide general information about the service itself and specific information about the name sources used. The output is XML as per the OWS Common standard [OWS].

Request Parameter Required / Optional Description
VERSION=2.0.0 Required Request version
REQUEST=GetCapabilities Required Request name

Sample request: http://host/path/to/postalcode/postalcode.cgi?version=2.0.0&request=GetCapabilities

DescribePostalCode

The purpose of the DescribePostalCode operation is to return the GML application schema for the FSA content model.

Request Parameter Required / Optional Description
VERSION=2.0.0 Required Request version
REQUEST=DescribePostalCode Required Request name

Sample request: http://host/path/to/postalcode/postalcode.cgi?version=2.0.0&request=DescribePostalCode

GetPostalCode

The purpose of the GetPostalCode operation is to return the geometries for a placename inputted by a request.

Request Parameter Required / Optional Description
VERSION=2.0.0 Required Request version
REQUEST=GetPostalCode Required Request name
CODE=fsa Required FSA code, case insensitive

Below is the content model returned by a GetPostalCode response:

CGDI Postal Code Service FSA Content Model

Sample request: http://host/path/to/postalcode/postalcode.cgi?version=2.0.0&request=GetPostalCode&code=m9c

Response:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<PostalCodeLookup xmlns="http://www.cgdi.ca/postalcode" version="2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.cgdi.ca/postalcode http://devgeo.cciw.ca/postalcode/postalcode.cgi?version=2.0.0&amp;request=DescribePostalCode">
    <gml:boundedBy>
        <gml:Null>inapplicable</gml:Null>
    </gml:boundedBy>
    <PostalCodeResultSet sortArea="FSA">
        <PostalCode>
            <gml:name>M9C</gml:name>
            <Placename>Etobicoke</Placename>
            <ProvinceOrTerritory>ON</ProvinceOrTerritory>
            <gml:centerOf>
                <gml:Point srsName="urn:ogc:def:crs:EPSG:6.6:4326" srsDimension="2">
                    <gml:pos>43.642063 -79.575493</gml:pos>
                </gml:Point>
            </gml:centerOf>
        </PostalCode>
    </PostalCodeResultSet>
</PostalCodeLookup>

Exceptions

The service will return OGC ExceptionReport documents on invalid requests, as per OWS Common [OWS].

<?xml version="1.0" encoding="ISO-8859-1"?>
<ExceptionReport xmlns="http://www.opengis.net/ows/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/ows/2.0 http://schemas.opengis.net/ows/2.0/owsExceptionReport.xsd" version="2.0.0" xml:lang="en-CA">
    <Exception locator="request" exceptionCode="InvalidParameterValue">
        <ExceptionText>Invalid value for request: invalidrequestname</ExceptionText>
    </Exception>
</ExceptionReport>

Client Access

Since the CGDI Postal Code Lookup Service is a Web Service, any programming language which can make HTTP requests and parse XML can be used.

Python

Here’s a simple Python script to fetch FSA ‘m9c’:

#!/usr/bin/python

import urllib2
from lxml import etree

url = 'http://host/path/to/postalcode/postalcode.cgi?version=2.0.0&request=GetPostalCode&code=m9c'
content = urllib2.urlopen(url)
doc = etree.parse(content)

postalcode = doc.find('{http://www.cgdi.ca/postalcode}PostalCodeResultSet/{http://www.cgdi.ca/postalcode}PostalCode')

code = postalcode.find('{http://www.opengis.net/gml}name').text
placename = postalcode.find('{http://www.cgdi.ca/postalcode}Placename').text
provterr = postalcode.find('{http://www.cgdi.ca/postalcode}ProvinceOrTerritory').text
coords = postalcode.find('{http://www.opengis.net/gml}centerOf/{http://www.opengis.net/gml}Point/{http://www.opengis.net/gml}pos').text

# ...

JavaScript

Here’s a simple JavaScript function using jQuery (note that a proxy wrapper script is required [proxy_url]):

jQuery(document).ready(function(){
    // set up an HTML form element with id="postalForm" and input text box with id="postal"
    jQuery('#postalForm').submit(zoomToPostalCode);

// ...

function zoomToPostalCode() {
    var proxy_url = 'http://host/path/to/proxy';
    var url = proxy_url +
    escape('http://host/path/to/postalcode/postalcode.cgi?version=2.0.0&request=GetPostalCode&code=') + jQuery('input#postal').val();

    jQuery.get(url,{},function(xml){
        jQuery('PostalCode',xml).each(function(i) {
            var code = jQuery(this).find('gml\\:name').text();
            var placename = jQuery(this).find('Placename').text();
            var provterr = jQuery(this).find('ProvinceOrTerritory').text();
            var coords = jQuery(this).find('gml\\:pos').text();
            // ...
        });
    });
    return false;
}

Python direct module access

Here’s a simple example of local interaction with the Python module:

$ cd /path/to/postalcode
$ python
Python 2.6.2 (r262:71600, Aug 21 2009, 12:22:21)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from postalcode import fsa
>>> help(fsa)
... help text
>>> fsa.getfsa('/path/to/postalcode/data/fsa.csv','m9c')
{'placename': 'Etobicoke', 'code': 'M9C', 'success': True, 'sortarea': 'FSA', 'longitude': '-79.575493', 'provinceorterritory': 'ON', 'latitude': '43.642063'}
>>> fsa.getfsa('/path/to/postalcode/data/fsa.csv','invalidcode')
{'locator': 'code', 'code': 'InvalidParameterValue', 'success': False, 'text': 'Invalid code value: INVALIDCODE'}
>>>

References

[GML]Open Geospatial Consortium, 2004, OpenGIS Geography Markup Language (GML) Encoding Standard 3.1.1, http://portal.opengeospatial.org/files/?artifact_id=4700.
[OWS](1, 2) Open Geospatial Consortium, 2010, OGC Web Service Common Implementation Specification 2.0.0, http://portal.opengeospatial.org/files/?artifact_id=38867.