#!/usr/bin/env perl
# mhziptodb - Creates a database using Civic Space Labs zipcode data
# License:  Creative Commons Attribution-NonCommercial-ShareAlike 2.5
# Revision: 081026

# Note:  The license indicated above applies to this file,  and not to
# the data used.  The data is distributed under the following license:
# Creative Commons Attribution-ShareAlike 2.0.

#---------------------------------------------------------------------
#                         license information
#---------------------------------------------------------------------

# This notice may not be  modified  except as  approved by  the author
# (and licensor), or to make non-content changes related to HTML tags,
# paragraph formatting, white space, etc.

# This software is distributed under the following license:
#
#     Creative Commons Attribution-NonCommercial-ShareAlike 2.5

# You may use, modify, and redistribute this software  without fees or
# royalties,  but only under the terms and conditions set forth by the
# license.  In particular, copies and derived works cannot be used for
# commercial purposes.  Additionally, the license propagates to copies
# and derived works. Furthermore, you must provide attribution "in the
# manner  specified  by the  author or licensor".  The latter point is
# discussed below.

# The author (and licensor) hereby specifies that  attribution must be
# handled in the following manner:  a. If the software is interactive,
# any About or Credits dialog boxes, windows, or text  provided by the
# original version must be preserved and operational. b. Additionally,
# whether or not clause (a) applies, the operating system and/or desk-
# top environment used must provide attribution that is readily acces-
# sible to the  end user at runtime. Note: "Readily accessible"  means
# that  attribution  should be  directly accessible  from  the desktop
# environment's highest-level Start menu or a similar location.

# The following techniques do *not* meet the attribution requirements:
# Attribution through  text files  whose contents aren't actually dis-
# played, attribution  through printed documentation,  verbal attribu-
# tion, or postings on external web sites (i.e., web sites that aren't
# an  intrinsic  local component of the  operating system  or  desktop
# environment used). These examples are provided for illustrative pur-
# poses only.

# It should be noted that trademarks are an additional issue.  If this
# software uses any trademarks, trademark-related restrictions may ap-
# ply.

# This  isn't a  complete explanation of the  terms and conditions in-
# volved.  For more information,  see the  applicable Creative Commons
# Attribution NonCommercial ShareAlike license[s].  If Internet access
# is enabled, the official copies of these license[s] should be avail-
# able at:
#
#     http://creativecommons.org/

#---------------------------------------------------------------------
#                           important note
#---------------------------------------------------------------------

# This software is provided on an  AS IS basis with ABSOLUTELY NO WAR-
# RANTY.  The  entire risk as to the  quality and  performance of  the
# software is with you.  Should the software prove defective,  you as-
# sume the cost of all necessary  servicing, repair or correction.  In
# no event will any of the developers,  or any other party, be  liable
# to anyone for damages arising out of use of the software, or inabil-
# ity to use the software.

#---------------------------------------------------------------------
#                              overview
#---------------------------------------------------------------------

# "mhziptodb" is used when the "ziptoloc" package is built.  This scr-
# ipt takes a specific CSV-format data file named "zipcode.csv" as in-
# put;  specifically,  the version of  "zipcode.csv" created by  Civic
# Space Labs in 2004.  It  generates a  Berkeley-format  database file
# named  "ziptoloc.db" as  output. For more information, see the "zip-
# toloc" source code.

#---------------------------------------------------------------------
#                        standard module setup
#---------------------------------------------------------------------

require 5.8.1;
use strict;
use Carp;
use warnings;
                                # Trap warnings
$SIG {__WARN__} = sub { die @_; };

#---------------------------------------------------------------------
#                         additional modules
#---------------------------------------------------------------------

use DB_File;                    # CPAN     module
use Fcntl;                      # Built-in module

#---------------------------------------------------------------------
#                           basic constants
#---------------------------------------------------------------------

use constant ZERO  => 0;        # Zero
use constant ONE   => 1;        # One

use constant FALSE => 0;        # Boolean FALSE
use constant TRUE  => 1;        # Boolean TRUE

#---------------------------------------------------------------------
#                         program parameters
#---------------------------------------------------------------------

                                # Input  -file name
my $DBFILE_INPUT  = 'zipcode.csv';
                                # Output -file name
my $DBFILE_OUTPUT = 'ziptoloc.db';

#---------------------------------------------------------------------
#                            main routine
#---------------------------------------------------------------------

sub Main
{
    my  %ZipToLoc = ();         # Maps ZIP codes to locations
                                # Connect hash table to output file
    tie %ZipToLoc, "DB_File", $DBFILE_OUTPUT, O_RDWR|O_CREAT, 0660;

                                # Open the input file
    open (IFD, "<$DBFILE_INPUT") ||
        die "Error: Can't open $DBFILE_INPUT: $!\n";

    while (<IFD>)               # Process the  input file
    {                           # Process next input line
        s@\s+\z@@s;
        s@\s*,\s*@,@g;
        s@\s+@ @g;
        s@"@@g;
        my @fields = split (/,/, $_);
        next unless scalar @fields == 7;

        my ($zipcode, $latitude, $longitude) =
            ($fields [ZERO], $fields [3], $fields [4]);
        next unless defined ($zipcode) && ($zipcode =~ m@^\d{5}\z@);

        $latitude  =~ s@^\s+@@; $latitude  =~ s@\.\z@@;
        $longitude =~ s@^\s+@@; $longitude =~ s@\.\z@@;

        $ZipToLoc {$zipcode} = "$latitude\000$longitude";
    }

    close IFD;                  # Close the input  file
    untie %ZipToLoc;            # Close the output file
                                # Print a status message
    print "Created $DBFILE_OUTPUT\n";
    undef;
}

#---------------------------------------------------------------------
#                            main program
#---------------------------------------------------------------------

&Main();                        # Call the main routine
exit ZERO;                      # Normal exit
