确定邮政编码邻近/范围的 MySQL 函数
Posted
技术标签:
【中文标题】确定邮政编码邻近/范围的 MySQL 函数【英文标题】:MySQL Function to Determine Zip Code Proximity / Range 【发布时间】:2010-08-22 23:24:08 【问题描述】:我已经能够创建 php 函数来确定给定邮政编码的特定范围内的邮政编码列表。但是,我的下一个任务要复杂一些。
假设该表具有以下列:
id,
username
info
latitude
longitude
range
每条记录都有一个唯一的行 ID、一些信息、一个纬度、一个经度以及人们希望找到该条目的坐标的最大范围。因此,如果我创建一个坐标为 -20、50、范围为 15 的条目,这意味着我只希望坐标 -20、50 15 英里内的人能够看到我的条目。弄清楚运行搜索的用户的纬度和经度是一件小事。
当用户在数据库中搜索时,所有记录都应该在用户lat/long的范围值内检索经纬度坐标。
因此,使用距离公式来说明这一点的非功能性代码示例是
$userLat
= 运行搜索的用户的纬度
$userLong
= 运行搜索的用户的经度
SELECT info FROM table
WHERE sqrt(($userLat - lat)^2 - ($userLong - long)^2) <= range
ORDER BY username ASC
这将是理想的,但从编码的角度来看它是无效的。有没有办法在一个查询中使用 PHP 和 mysql 运行上述比较?这将涉及能够使用给定行中的多个列值运行操作。
更新 + 解决方案
我创建了另一个问题条目来解决这个问题,并且有一个非常紧凑的函数来做这个问题想要的。 coderpros 提供的功能是它的灵感来源(他的功能在某些情况下具有更好的处理能力)。但是,由于我使用的函数对输入有很大程度的控制,所以我创建了一个单独的函数。它可以在下面的链接中找到:
MySQL User Defined Function for Latitude Longitude Syntax
【问题讨论】:
【参考方案1】:我编写的这个漂亮的 lil mySQL 函数绝对可以为您解决问题。
BEGIN
DECLARE x decimal(18,15);
DECLARE EarthRadius decimal(7,3);
DECLARE distInSelectedUnit decimal(18, 10);
IF originLatitude = relativeLatitude AND originLongitude = relativeLongitude THEN
RETURN 0; -- same lat/lon points, 0 distance
END IF;
-- default unit of measurement will be miles
IF measure != 'Miles' AND measure != 'Kilometers' THEN
SET measure = 'Miles';
END IF;
-- lat and lon values must be within -180 and 180.
IF originLatitude < -180 OR relativeLatitude < -180 OR originLongitude < -180 OR relativeLongitude < -180 THEN
RETURN 0;
END IF;
IF originLatitude > 180 OR relativeLatitude > 180 OR originLongitude > 180 OR relativeLongitude > 180 THEN
RETURN 0;
END IF;
SET x = 0.0;
-- convert from degrees to radians
SET originLatitude = originLatitude * PI() / 180.0,
originLongitude = originLongitude * PI() / 180.0,
relativeLatitude = relativeLatitude * PI() / 180.0,
relativeLongitude = relativeLongitude * PI() / 180.0;
-- distance formula, accurate to within 30 feet
SET x = Sin(originLatitude) * Sin(relativeLatitude) + Cos(originLatitude) * Cos(relativeLatitude) * Cos(relativeLongitude - originLongitude);
IF 1 = x THEN
SET distInSelectedUnit = 0; -- same lat/long points
-- not enough precision in MySQL to detect this earlier in the function
END IF;
SET EarthRadius = 3963.189;
SET distInSelectedUnit = EarthRadius * (-1 * Atan(x / Sqrt(1 - x * x)) + PI() / 2);
-- convert the result to kilometers if desired
IF measure = 'Kilometers' THEN
SET distInSelectedUnit = MilesToKilometers(distInSelectedUnit);
END IF;
RETURN distInSelectedUnit;
END
它以 originLatitude、originLongitude、relativeLatitude、relativeLongitude 和 measure 作为参数。度量可以简单地是Miles
或Kilometers
希望有帮助!
【讨论】:
非常感谢您快速且内容丰富的回复。请原谅我的白痴,但我对使用自定义 mysql 函数并不熟悉。我将如何将它与 php 一起使用? 好吧,你需要做的是在你的mysql数据库中创建上面的函数,然后你可以在你的php中调用它,如下所示: $sql = "SELECT * FROM users WHERE CalculateDistance(userLat,userLong , relLat, relLong,'miles) 啊,明白了。只有最后一件事,我应该准备好使用它。在下面的部分中: CalculateDistance(userLat,userLong, relLat, relLong,'miles) 没问题。你完全正确。让我知道你是否卡在任何地方。 我还没有足够的声望点来投票赞成这个回复,但非常感谢。这很有帮助。以上是关于确定邮政编码邻近/范围的 MySQL 函数的主要内容,如果未能解决你的问题,请参考以下文章