=pod

=encoding utf-8

=head1 NAME

Geo::UK::Postcode - Object and class methods for working with British postcodes.

=head1 VERSION

version 0.006

=head1 SYNOPSIS

  # See Geo::UK::Postcode::Regex for parsing/matching postcodes

  use Geo::UK::Postcode;
  
  my $pc = Geo::UK::Postcode->new( "wc1h9eb" );
  
  $pc->raw;            # wc1h9eb - as entered
  $pc->as_string;      # WC1H 9EB - output in correct format
  "$pc";               # stringifies, same output as '->as_string'
  $pc->fixed_format;   # 8 characters, the incode always last three
  
  $pc->area;           # WC
  $pc->district;       # 1
  $pc->subdistrict;    # H
  $pc->sector;         # 9
  $pc->unit;           # EB
  
  $pc->outcode;        # WC1H
  $pc->incode;         # 9EB
  
  $pc->strict;     # true if matches strict regex
  $pc->valid;      # true if matches strict regex and has a valid outcode
  $pc->partial;    # true if postcode is for a district or sector only

  $pc->non_geographical;    # true if outcode is known to be
                            # non-geographical

  # Sort Postcode objects:
  use Geo::UK::Postcode qw/ pc_sort /;
  
  my @sorted_pcs = sort pc_sort @unsorted_pcs;

=head1 DESCRIPTION

An object to represent a British postcode.

For matching and parsing postcodes in a non-OO manner (for form validation, for
example), see L<Geo::UK::Postcode::Regex>

For geo-location (finding latitude and longitude) see L</"GEO-LOCATING POSTCODES">.

Currently undef development - feedback welcome. Basic API unlikely to change
greatly, just more features/more postcodes supported - see L</TODO> list.

=for Pod::Coverage BUILDARGS BUILD

=head1 METHODS

=head2 raw

Returns exact string that the object was constructed from.

=head2 as_string

  $pc->as_string;

  # or:

  "$pc";

Stringification of postcode object, returns postcode with a single space
between outcode and incode.

=head2 fixed_format

    my $fixed_format = $postcode->fixed_format;

Returns the full postcode in a fixed length (8 character) format, with extra
padding spaces inserted as necessary.

=head2 area, district, subdistrict, sector, unit

Return the corresponding part of the postcode, undef if not present.

=head2 outcode

The first half of the postcode, before the space - comprises of the area and
district.

=head2 incode

The second half of the postcode, after the space - comprises of the sector
and unit. Returns an empty string if not present.

=head2 outward, inward

Aliases for C<outcode> and C<incode>.

=head2 valid

  if ($pc->valid) {
    ...
  }

Returns true if postcode has valid outcode and matches strict regex.

=head2 partial

  if ($pc->partial) {
    ...
  }

Returns true if postcode is not a full postcode, either a postcode district
( e . g . AB10 )
or postcode sector (e.g. AB10 1).

=head2 strict

  if ($pc->strict) {
    ...
  }

Returns true if postcode matches strict regex, meaning all characters are valid
( although postcode might not exist ) .

=head2 non_geographical

    if ($pc->non_geographical) {
      ...
    }

Returns true if the outcode is known to be non-geographical. Note that
geographical outcodes may have non-geographical postcodes within them.

(Non-geographical postcodes are used for PO Boxes, or organisations
receiving large amounts of post).

=head2 bfpo

    if ($pc->bfpo) {
        ...
    }

Returns true if postcode is mapped to a BFPO number (British Forces Post
Office).

=head2 posttowns

    my (@posttowns) = $postcode->posttowns;

Returns list of one or more posttowns that this postcode is assigned to.

=head1 EXPORTABLE

=head2 pc_sort

    my @sorted_pcs = sort pc_sort @unsorted_pcs;

Exportable sort function, sorts postcode objects in a useful manner. The
sort is in the following order: area, district, subdistrict, sector, unit
(ascending alphabetical or numerical order as appropriate).

=head1 GEO-LOCATING POSTCODES

Postcodes can be geolocated by obtaining the Ordnance Survey 'Code-Point' data
(or the free 'Code-Point Open' data).

For full details of using this class with Code-Point data, see:
L<Geo::UK::Postcode::Manual::Geolocation>.

=head1 SEE ALSO

=over

=item *

L<Geo::UK::Postcode::Regex>

=item *

L<Geo::Address::Mail::UK>

=item *

L<Geo::Postcode>

=back

=head1 TODO

=over

=item Finalise API

=item Handle non-geographic postcodes

=item Handle British overseas territories

=item Handle special case postcodes, like GIR 0AA and SAN TA1

=item Find out which BX non-geographical districts are used.

=item handle BFPO

=item cleanup method to correct common errors

=back

=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan

=head1 SUPPORT

=head2 Bugs / Feature Requests

Please report any bugs or feature requests through the issue tracker
at L<https://github.com/mjemmeson/geo-uk-postcode/issues>.
You will be notified automatically of any progress on your issue.

=head2 Source Code

This is open source software.  The code repository is available for
public review and contribution under the terms of the license.

L<https://github.com/mjemmeson/geo-uk-postcode>

  git clone git://github.com/mjemmeson/geo-uk-postcode.git

=head1 AUTHOR

Michael Jemmeson <mjemmeson@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2013 by Michael Jemmeson <mjemmeson@cpan.org>.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

