我正在使用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
谢谢!
答案 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)) "
如果有人可以发表评论并解释这一变化的作用,我将不胜感激。