php - 有人能帮我弄清楚为什么这个邮政编码类找不到范围内的邮政编码吗?

标签 php mysql

我正在使用来自 https://github.com/Quixotix/PHP-ZipCode-Class 的类(class)创建邮政编码定位器。它大部分时间都有效,但有时,类中的一个函数似乎不起作用。例如,如果我这样做:

<?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;
    }
?>

完整类(class)您可以在这里查看:https://github.com/Quixotix/PHP-ZipCode-Class/blob/master/zipcode.php

谢谢!

最佳答案

好吧,我修复了它,但我不确定如何......我只是玩数字,任何时候除以 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)) "

如果有人可以发表评论并解释此更改的作用,我将不胜感激。

关于php - 有人能帮我弄清楚为什么这个邮政编码类找不到范围内的邮政编码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29977716/

相关文章:

php - 即时更改语言 codeigniter

php - 使用 CI 语句中的 where 防止重复结果

javascript - Ninja Forms 服务器端验证在 "Processing"上卡住

php - 多条件查询记录

mysql - 如何从学生类(class)关联表中选择给定学生的同学?

mysql - 在 Windows 上使用 OpenSSL 从源代码编译 MySQL

php - 比较PHP中的两个unicode字符串

MySQL LEFT JOIN 使用条件运算符(>= 和 <)不返回连接表的空值

php - 通过 Magento 中的单个 MySQL 查询删除特定类别及其所有子类别的所有产品

mysql - 关于 Laravel4 中的重复键更新查询