A friend does some geographic statistics stuff. He told me he was manually entering postal codes into a program one at a time to get the latitude and longitude.

I figured there might be a module on CPAN. I wrote a short program using Geo::Coder::Canada for him to use. It reads from stdin so I just piped a CSV file he gave me into the program.

It turned out he wanted a CSV file to import into a spreadsheet. By then I already had the human readable output and each postal code takes a second to lookup so I used Emacs rectangle functions to fix up the columns but it would be easy to change the code to print the results in CSV.

The code finds the first postal code on each line of input so it's kind of smart when fed a full address or quotes around the postal code. A sample run looks like:
$ ./geocode-canada.pl Enter a Canadian Postal Code and press enter. Repeat until you are done. Press control-c or control-d to exit. t2s 0b3 t2s 0b3 , Lat: 51.037821 , Long: -114.074626 t2e0c1 t2e0c1 , Lat: 51.053263 , Long: -114.045510 T3C 0X7 T3C 0X7 , Lat: 51.039459 , Long: -114.092120 "T3E 0B1" T3E 0B1 , Lat: 51.037782 , Long: -114.128998 No postal code found in input 2500 University Drive N.W. No postal code found in input Calgary, Alberta, No postal code found in input T2N 1N4 T2N 1N4 , Lat: 51.074892 , Long: -114.129012
Update: Thanks to jwkrahn for making the regex that looks for a valid postal code more specific.

The code is:
#! /usr/bin/perl -w # file: geocode-canada.pl # purpose: find Lat/Lon values from Canadian postal code values use strict; use Data::Dumper; use Geo::Coder::Canada; print qq/ Enter a Canadian Postal Code and press enter. Repeat until you are done. Press control-c or control-d to exit. /; LINE: while(my $line = <>) { my $postal; # improved by jwkrahn # unless ($line =~ m/([A-Z]\d[A-Z]\s*\d[A-Z]\d)/i) { unless ( $line =~ m/([ABCEGHJ-NPRSTVXY][0-9][ABCEGHJ-NPRSTV-Z]\s*[ +0-9][ABCEGHJ-NPRSTV-Z][0-9])/i ) { print "No postal code found in input\n"; next LINE; } $postal = $1; my $g = Geo::Coder::Canada->new; $g->postal($postal); if ($g->geocode) { #print Dumper($g); my $result = $g->geo_result(); my $latitude = $result->latt; my $longitude = $result->longt; print $g->postal(), "\t, Lat: " , $latitude , "\t, Long: " , $ +longitude , "\n"; } else { #print Dumper($g); my $geodata = $g->geodata(); #print Dumper($geodata); print $geodata->{error}->{description} , "(code ", $geodata->{error}->{code} , ")" , "\n"; } }

In reply to Get latitude and longitude from Canadian postal codes by superfrink

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.