<?php
/* /
  File:  ZipProximality.phi
  Purpose:  Code to operate latitude/longitude mathematics and correlate it to zip codes utilizing a pre-established database table.
  Created:  3/2007 - Locke Enterprises (www.iLocke.com)
  Modification History:
  � 03/07/2007 - Nathan - initial dataset utilized from the Ultimate Locator (c) 2005
  � 03/24/2007 - Nathan - added in the zip code distance search aspect of this
  � 03/02/2008 - Nathan - had to fix the temporary CREATE table statement
  � 11/05/2009 - Nathan - added the function to get all zips prefixes within the range of another
  � 11/24/2009 - Nathan - added a way to return the proximal warehouses
  � 12/03/2009 - Nathan - table name and temp customization parameters; and debug flag
  � 12/30/2013 - Nathan - adjusted to run on MySQL 5.5 (engine=MENORY instead of type=HEAP)
  � mm/dd/yyyy - [name] - [comment]
  NOTE: !! Missing the 2-digit calc code for AGH !!
  / */

// main; installers and warehouses (now with table+temp options)
?><?php
/* /	File:  ZipProximality.phi	Purpose:  Code to operate latitude/longitude mathematics and correlate it to zip codes utilizing a pre-established database table.	Created:  3/2007 - Locke Enterprises (www.iLocke.com)	Modification History:		� 03/07/2007 - Nathan - initial dataset utilized from the Ultimate Locator (c) 2005		� 03/24/2007 - Nathan - added in the zip code distance search aspect of this		� 03/02/2008 - Nathan - had to fix the temporary CREATE table statement		� 11/24/2009 - Nathan - added a way to return the proximal warehouses		� 12/03/2009 - Nathan - table name and temp customization parameters; and debug flag		� 12/30/2013 - Nathan - adjusted to run on MySQL 5.5 (engine=MENORY instead of type=HEAP)		� mm/dd/yyyy - [name] - [comment]	NOTE: !! Missing the 2-digit calc code for AGH !!/ */ define('ZIPPROXIMALITY_TABLE_TEMP', "_zipsearch");

function & ZipProximals_GetShops($zip, $radius = 300, $maxToCheck = 5000, $maxToReturn = 5000, $table = ZIPPROXIMALITY_TABLE_TEMP, $temporary = true, $bDebug = false) {
    $ProximalZips = ZipProximality_GetZipList($zip, $radius, $maxToCheck, $table, $temporary, $bDebug);
    $oNRS = ZipProximality_ShopsFromList($ProximalZips, $maxToReturn, $table, $bDebug);
    return $oNRS;
}

function & ZipProximals_GetWarehouses($zip, $radius = 300, $maxToCheck = 500, $maxToReturn = 500, $table = ZIPPROXIMALITY_TABLE_TEMP, $temporary = true, $bDebug = false) {
    $ProximalZips = ZipProximality_GetZipList($zip, $radius, $maxToCheck, $table, $temporary, $bDebug);
    $oNRS = ZipProximality_WarehousesFromList($ProximalZips, $maxToReturn, $table, $bDebug);
    return $oNRS;
}

function & ZipProximality_ShopsFromList(&$ZipList, $maxToReturn = 500, $table = ZIPPROXIMALITY_TABLE_TEMP, $bDebug = false) {
    if (substr($table, 0, 1) != "_")
        $table = '_' . $table;
    $SQL = " SELECT " . $table . ".distance, location.* FROM location LEFT JOIN " . $table . " ON location.zip=" . $table . ".zip WHERE location.zip IN(" . $ZipList . ") ORDER BY distance LIMIT " . $maxToReturn . " ";
    if ($bDebug === true)
        echo "<p>" . $SQL . "</p>";
    $oNRS = new nRS($SQL);
    return $oNRS;
}

function & ZipProximality_WarehousesFromList(&$ZipList, $maxToReturn = 500, $table = ZIPPROXIMALITY_TABLE_TEMP, $bDebug = false) {
    if (substr($table, 0, 1) != "_")
        $table = '_' . $table;
    $SQL = " SELECT " . $table . ".distance, warehouse.* FROM warehouse LEFT JOIN " . $table . " ON warehouse.pickupZip=" . $table . ".zip WHERE warehouse.pickupZip IN(" . $ZipList . ") ORDER BY distance LIMIT " . $maxToReturn . " ";
    if ($bDebug === true)
        echo "<p>" . $SQL . "</p>";
    $oNRS = new nRS($SQL);
    return $oNRS;
}

function & ZipProximality_GetZipList($zip, $radius = 500, $maxToCheck = 2500, $table = ZIPPROXIMALITY_TABLE_TEMP, $temporary = true, $bDebug = false) {
    global $g_oNDB;
    $rOrigin = $g_oNDB->getRow("SELECT * FROM zipcode WHERE zipcode='" . addslashes($zip) . "'");
    if ($bDebug === true)
        echo "<pre>" . print_r($rOrigin, true) . "</pre>";if (substr($table, 0, 1) != "_")
        $table = '_' . $table;
    $SQL = "DROP TABLE IF EXISTS " . $table;
    if ($bDebug === true)
        echo "<p>" . $SQL . "</p>";
    $g_oNDB->execute($SQL);
    $SQL = " create " . ($temporary ? "TEMPORARY " : "") . "table " . $table . "( zip char(10) NOT NULL default '', latitude double NOT NULL default 0.00, longitude double NOT NULL default 0.00, distance double NOT NULL default 0.00, primary key(zip) ) engine=MEMORY ";
    if ($bDebug === true)
        echo "<p>" . $SQL . "</p>";
    $g_oNDB->execute($SQL);
    $SQL = " INSERT INTO " . $table . "(zip,latitude,longitude,distance) SELECT zipcode, latitude,longitude, DEGREES( ACOS( SIN(RADIANS(" . $rOrigin['latitude'] . ")) * SIN(RADIANS(latitude)) + COS(RADIANS(latitude)) * COS(RADIANS(" . $rOrigin['latitude'] . ")) * COS(RADIANS(" . $rOrigin['longitude'] . " - longitude)) ) )*60*1.1515 as calc_distance FROM zipcode WHERE " . $radius . " > DEGREES( ACOS( SIN(RADIANS(" . $rOrigin['latitude'] . ")) * SIN(RADIANS(latitude)) + COS(RADIANS(latitude)) * COS(RADIANS(" . $rOrigin['latitude'] . ")) * COS(RADIANS(" . $rOrigin['longitude'] . " - longitude)) ) )*60*1.1515 ";
    if ($bDebug === true)
        echo "<p>" . $SQL . "</p>";
    $g_oNDB->execute($SQL);
    $SQL = "SELECT zip, distance FROM " . $table . " WHERE distance < " . $radius . " ORDER BY distance LIMIT " . $maxToCheck;
    if ($bDebug === true)
        echo "<p>" . $SQL . "</p>";
    $oNRS = new nRS($SQL);
    for ($i = 0; $i < mysql_num_rows($oNRS->hData); $i++) {
        $zips .= "'" . mysql_result($oNRS->hData, $i, "zip") . "',";
    } if ($zips != "")
        $zips = substr($zips, 0, strlen($zips) - 1);
    return $zips;
}
?><?php
// agh: 2-digit prefixes
?>
<?php /* / File: ZipProximality.phi Purpose: Code to operate latitude/longitude mathematics and correlate it to zip codes utilizing a pre-established database table. Created: 3/2007 - Locke Enterprises (www.iLocke.com) Modification History: � 03/07/2007 - Nathan - initial dataset utilized from the Ultimate Locator (c) 2005 � 03/24/2007 - Nathan - added in the zip code distance search aspect of this � 03/02/2008 - Nathan - had to fix the temporary CREATE table statement � 11/05/2009 - Nathan - added the function to get all zips prefixes within the range of another � 11/24/2009 - Nathan - added a way to return the proximal warehouses � 12/03/2009 - Nathan - table name and temp customization parameters; and debug flag � 12/30/2013 - Nathan - adjusted to run on MySQL 5.5 (engine=MENORY instead of type=HEAP) � mm/dd/yyyy - [name] - [comment] NOTE: !! Missing the 2-digit calc code for AGH !! / */ 
function & ZipProximality_GetPrefixesInRange( $zip, $radius = 40, $prefixlength = 2, $limit = 2500 ) { 
global $g_oNDB;
$rOrigin = $g_oNDB->getRow("SELECT * FROM zipcode WHERE zipcode='".addslashes($zip)."'");
$SQL = " create temporary table _zipsearchprefix( zip char(10) NOT NULL default '', latitude double NOT NULL default 0.00, longitude double NOT NULL default 0.00, distance double NOT NULL default 0.00, primary key(zip) ) engine=MEMORY ";
$g_oNDB->execute( $SQL );
$SQL = " INSERT INTO _zipsearchprefix(zip,latitude,longitude,distance) SELECT zipcode, latitude,longitude, DEGREES( ACOS( SIN(RADIANS(".$rOrigin['latitude'].")) * SIN(RADIANS(latitude)) + COS(RADIANS(latitude)) * COS(RADIANS(".$rOrigin['latitude'].")) * COS(RADIANS(".$rOrigin['longitude']." - longitude)) ) )*60*1.1515 as calc_distance FROM zipcode WHERE ".$radius." > DEGREES( ACOS( SIN(RADIANS(".$rOrigin['latitude'].")) * SIN(RADIANS(latitude)) + COS(RADIANS(latitude)) * COS(RADIANS(".$rOrigin['latitude'].")) * COS(RADIANS(".$rOrigin['longitude']." - longitude)) ) )*60*1.1515 ";
$g_oNDB->execute( $SQL );
if( $prefixlength < 1 ) $prefixlength = 1;
if( $prefixlength > 5 ) $prefixlength = 5;
$zips = array();
$SQL = "SELECT Distinct(Mid(zip,1,".$prefixlength.")) as `prefix` FROM _zipsearchprefix LIMIT ".$limit;
$oNRS = new nRS($SQL);
while( $rData = $oNRS->read() ) { $zips[] = $rData['prefix'];
} return $zips;
} ?>