php - 确定邮政编码邻近度/范围的 MySQL 函数

标签 php mysql function zipcode proximity

我已经能够创建 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

最佳答案

我编写的这个漂亮的 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 作为参数。度量单位可以是 MilesKilometers

希望对您有所帮助!

关于php - 确定邮政编码邻近度/范围的 MySQL 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3543890/

相关文章:

php.activerecord 通配符不起作用吗?

php - 重写Wordpress核心函数_wp_mysql_week()

php - 使用多个标记在 map 上绘制路线,CodeIgniter

MySQL count(*) 、Group BY 和 INNER JOIN

mysql - 如何通过mysql获取接下来的三个工作日(当前数据和接下来的三天)

javascript - 替换的函数访问封装对象?

c - 确定函数的 Big-O 表示法

javascript - 在javascript中动态获取php数组

php - 使用 CodeIgniter 重定向

php - 如何将 Laravel/Eloquent 结果映射到自定义类