我已经在SaniSoft找到了这个名为Zip Location的流行的PHP / MySQL脚本,除了一件事之外它还很有用:在某些情况下它并不适用。
似乎任何20英里以下的半径都会返回与20英里相同数量的邮政编码。我搜遍了谷歌,但无济于事,我想知道是否有人对这种情况有所了解。
我宁愿在支付一个程序之前弄清楚这个问题,我也可以使用学习经验。数据库是邮政编码列表以及每个邮政编码的经度和纬度。该脚本使用一种方法确定输入的邮政编码周围的距离,并根据其lon / lat返回该半径中的邮政编码。
谢谢!
编辑: 通过使用脚本提供的距离函数,我发现程序给我的邮政编码与我的邮政编码之间的距离为0英里。
主要更新
从研究中可以看出数据库具有重复的lat / lon值。使用Zip Locator时请注意这一点。虽然PHP可以完成它的工作,但您需要找到一个新的邮政编码数据库。我将在以后公布我的发现。
答案 0 :(得分:10)
以下近似距离计算相对简单,但是 可以产生10%以上的距离误差。这些近似 使用度中的纬度和经度值执行计算。第一个近似只需要简单的数学函数:
Approximate distance in miles = sqrt(x * x + y * y)
where
x = 69.1 * (lat2 - lat1)
and
y = 53 * (lon2 - lon1)
您可以通过以下方法提高此近似距离计算的准确度 添加余弦数学函数:
Approximate distance in miles = sqrt(x * x + y * y)
where
x = 69.1 * (lat2 - lat1)
and
y = 69.1 * (lon2 - lon1) * cos(lat1/57.3)
如果您需要更高的准确度,则必须使用精确的距离计算。 准确的距离计算需要使用球面几何,因为 地球是一个球体。精确的距离计算也需要很高的水平 浮点数学精度 - 大约15位精度 (有时称为“双精度”)。另外,trig数学 精确计算中使用的函数需要转换纬度 和经度值从度到弧度。转换纬度或 从度数到弧度的经度,除以纬度和经度值 在这个数据库中180 / pi,或57.2958。假设地球的半径为 为6,371公里,或3,958.75英里。
您必须在中包含度数到弧度的转换 计算。用度数代替弧度,计算如下:
Exact distance in miles = 3958.75 * arccos[sin(lat1/57.2958) *
sin(lat2/57.2958) +
cos(lat1/57.2958) *
cos(lat2/57.2958) *
cos(lon2/57.2958 - lon1/57.2958)]
答案 1 :(得分:1)
第二次尝试!
查看编辑过的问题陈述,我会看看你如何分配你的邮政编码。
如果您的邮政编码是整数而不是字符串,则可能会引入很多错误。最大的问题是美国邮政编码可以从0开始。
ziptest.php中的示例并不好,因为这种处理拉链为整数。当您尝试用整数描述我自己的邮政编码时:
$zip1 = 02446;
它被PHP解释为八进制值2446.phpZipLocator将该值用作字符串而不进行任何显式转换。因此,PHP将八进制2446的十进制值作为字符串(1318)给出,它根本不是邮政编码。
phpZipLocator没有通知它没有找到邮政编码,而是对给定半径内不存在的所有邮政编码进行半径搜索,它决定应该为1。
如果我使用字符串
设置邮政编码$zip1 = '02446';
我得到了正确的结果。
恕我直言,似乎phpZipLocator可以使用一点点工作。
答案 2 :(得分:0)
phpZipLocator(ziptest.php)演示脚本中半径的默认值使用20英里作为默认半径
$radius = 20;
$zipArray = $zipLoc->inradius($zipOne,$radius);
我的猜测是,$radius
的值仍在您的代码中并覆盖您要使用的半径。尝试对$radius
进行搜索和替换。
更好的是,使用调试器查看代码,并在调用$radius
时查看inradius()
是否设置为20。