有人可以帮我弄清楚为什么这个邮政编码类没有找到范围内的邮政编码?

时间:2015-04-30 21:04:35

标签: php mysql

我正在使用source中的一个类来创建邮政编码定位器。它大部分时间都有效,但是,有时候,类中的一个函数似乎不起作用。例如,如果我这样做:

<?php
//Include the class
require_once('zipcode.php');
$zipSearch=new ZipCode(51301);
$zipCode=$zipSearch->getZipCode();
echo round($zipSearch->getDistanceTo("56187"), 2);
?>

相对于英里,这将返回40.16,但是,如果我执行此操作:

<?php
//Include the class
require_once('zipcode.php');
$zipSearch=new ZipCode(51301);
$zipCode=$zipSearch->getZipCode();

foreach ($zipSearch->getZipsInRange(0, 100) as $miles => $zip) {
    $getMiles = round($miles, 1);
    $zipDistance["$zip"] = $getMiles;
}
?>

此邮政编码56187从未显示过。即使这个距离只有40.16。

我认为它必须执行与计算一起运行的选择查询,但说实话,我不够聪明,无法准确理解发生了什么。

这个功能只能获得2个邮政编码之间的距离并且有效:

<?php
private function calcDistanceSql($location)
    {
        $sql = 'SELECT 3956 * 2 * ATAN2(SQRT(POW(SIN((RADIANS(t2.lat) - '
              .'RADIANS(t1.lat)) / 2), 2) + COS(RADIANS(t1.lat)) * '
              .'COS(RADIANS(t2.lat)) * POW(SIN((RADIANS(t2.lon) - '
              .'RADIANS(t1.lon)) / 2), 2)), '
              .'SQRT(1 - POW(SIN((RADIANS(t2.lat) - RADIANS(t1.lat)) / 2), 2) + '
              .'COS(RADIANS(t1.lat)) * COS(RADIANS(t2.lat)) * '
              .'POW(SIN((RADIANS(t2.lon) - RADIANS(t1.lon)) / 2), 2))) '
              .'AS "miles" '
              ."FROM {$this->mysql_table} t1 INNER JOIN {$this->mysql_table} t2 ";


        switch ($this->location_type) {

            case ZipCode::LOCATION_ZIP:
                // note: zip code is sanitized in the constructor
                $sql .= "WHERE t1.zip_code = '{$this->zip_code}' ";
                break;

            case ZipCode::LOCATION_CITY_STATE:
                $city = @mysql_real_escape_string($this->city);
                $state = @mysql_real_escape_string($this->state_prefix);
                $sql .= "WHERE (t1.city = '$city' AND t1.state_prefix = '$state') AND t2.zip_code = '$zip_to'";
                break;

            default:
                throw new Exception('Invalid location type for '.__CLASS__);
        }

        switch (ZipCode::locationType($location))
        {
            case ZipCode::LOCATION_ZIP:
                $zip_to = $this->sanitizeZip($location);
                $sql .= "AND t2.zip_code = '$zip_to'";
                break;
            case ZipCode::LOCATION_CITY_STATE:
                $a = $this->parseCityState($location);
                $city = @mysql_real_escape_string($a[0]);
                $state = @mysql_real_escape_string($a[1]);
                $sql .= "AND (t2.city = '$city' AND t2.state_prefix = '$state')";
                break;
        }

        $r = @mysql_query($sql);

        if (!$r) {
            throw new Exception(mysql_error());
        }

        if (mysql_num_rows($r) == 0) {
            throw new Exception("Record does not exist calculating distance between $zip_from and $zip_to");
        }

        $miles = mysql_result($r, 0);
        mysql_free_result($r);

        return $miles;
    }
?>

以下是用于获取距离范围内所有邮政编码的功能,并且不会返回我要查找的邮政编码:

<?php
public function getZipsInRange($range_from, $range_to, $units=1)
    {
        if (empty($this->zip_code_id)) $this->setPropertiesFromDb();

        $sql = "SELECT 3956 * 2 * ATAN2(SQRT(POW(SIN((RADIANS({$this->lat}) - "
              .'RADIANS(z.lat)) / 2), 2) + COS(RADIANS(z.lat)) * '
              ."COS(RADIANS({$this->lat})) * POW(SIN((RADIANS({$this->lon}) - "
              ."RADIANS(z.lon)) / 2), 2)), SQRT(1 - POW(SIN((RADIANS({$this->lat}) - "
              ."RADIANS(z.lat)) / 2), 2) + COS(RADIANS(z.lat)) * "
              ."COS(RADIANS({$this->lat})) * POW(SIN((RADIANS({$this->lon}) - "
              ."RADIANS(z.lon)) / 2), 2))) AS \"miles\", z.* FROM {$this->mysql_table} z "
              ."WHERE zip_code <> '{$this->zip_code}' " 
              ."AND lat BETWEEN ROUND({$this->lat} - (25 / 69.172), 4) "
              ."AND ROUND({$this->lat} + (25 / 69.172), 4) "
              ."AND lon BETWEEN ROUND({$this->lon} - ABS(25 / COS({$this->lat}) * 69.172)) "
              ."AND ROUND({$this->lon} + ABS(25 / COS({$this->lat}) * 69.172)) "
              ."AND 3956 * 2 * ATAN2(SQRT(POW(SIN((RADIANS({$this->lat}) - "
              ."RADIANS(z.lat)) / 2), 2) + COS(RADIANS(z.lat)) * "
              ."COS(RADIANS({$this->lat})) * POW(SIN((RADIANS({$this->lon}) - "
              ."RADIANS(z.lon)) / 2), 2)), SQRT(1 - POW(SIN((RADIANS({$this->lat}) - "
              ."RADIANS(z.lat)) / 2), 2) + COS(RADIANS(z.lat)) * "
              ."COS(RADIANS({$this->lat})) * POW(SIN((RADIANS({$this->lon}) - "
              ."RADIANS(z.lon)) / 2), 2))) <= $range_to "
              ."AND 3956 * 2 * ATAN2(SQRT(POW(SIN((RADIANS({$this->lat}) - "
              ."RADIANS(z.lat)) / 2), 2) + COS(RADIANS(z.lat)) * "
              ."COS(RADIANS({$this->lat})) * POW(SIN((RADIANS({$this->lon}) - "
              ."RADIANS(z.lon)) / 2), 2)), SQRT(1 - POW(SIN((RADIANS({$this->lat}) - "
              ."RADIANS(z.lat)) / 2), 2) + COS(RADIANS(z.lat)) * "
              ."COS(RADIANS({$this->lat})) * POW(SIN((RADIANS({$this->lon}) - "
              ."RADIANS(z.lon)) / 2), 2))) >= $range_from "
              ."ORDER BY 1 ASC";

        $r = mysql_query($sql);
        if (!$r) {
            throw new Exception(mysql_error());
        }
        $a = array();
        while ($row = mysql_fetch_array($r, MYSQL_ASSOC))
        {
            // TODO: load ZipCode from array
            $a[$row['miles']] = new ZipCode($row);
        }

        return $a;
    }
?>

对于完整课程,您可以在此处查看:https://github.com/Quixotix/PHP-ZipCode-Class

谢谢!

1 个答案:

答案 0 :(得分:0)

嗯,我修好了,但是我不确定怎么样...我只是玩数字,任何时候有什么东西除以25我把它改成400.它现在返回我想要的结果,但是,我我不确定为什么......

我做的改变:

是:

."AND lat BETWEEN ROUND({$this->lat} - (25 / 69.172), 4) "
."AND ROUND({$this->lat} + (25 / 69.172), 4) "
."AND lon BETWEEN ROUND({$this->lon} - ABS(25 / COS({$this->lat}) * 69.172)) "
."AND ROUND({$this->lon} + ABS(25 / COS({$this->lat}) * 69.172)) "

将其更改为:

."AND lat BETWEEN ROUND({$this->lat} - (400 / 69.172), 4) "
."AND ROUND({$this->lat} + (400 / 69.172), 4) "
."AND lon BETWEEN ROUND({$this->lon} - ABS(400 / COS({$this->lat}) * 69.172)) "
."AND ROUND({$this->lon} + ABS(400 / COS({$this->lat}) * 69.172)) "

如果有人可以发表评论并解释这一变化的作用,我将不胜感激。