从经度和纬度坐标获取邮政编码

时间:2013-01-23 17:01:06

标签: mysql sql math

我有一个邮政编码表,我想知道如何创建一个包含latitudelongitude坐标的查询,并从中返回一个邮政编码。怎么办呢?

这是我的表结构:

mysql> describe zipcodes;
+-----------+-----------------------+------+-----+---------+----------------+
| Field     | Type                  | Null | Key | Default | Extra          |
+-----------+-----------------------+------+-----+---------+----------------+
| id        | bigint(20)            | NO   | PRI | NULL    | auto_increment | 
| zip       | mediumint(5) unsigned | NO   | MUL | NULL    |                | 
| longitude | varchar(15)           | NO   | MUL | NULL    |                | 
| latitude  | varchar(15)           | NO   | MUL | NULL    |                | 
| city      | varchar(25)           | NO   |     | NULL    |                | 
| state     | varchar(25)           | NO   |     | NULL    |                | 
| county    | varchar(25)           | NO   |     | NULL    |                | 
| zipClass  | varchar(25)           | NO   |     | NULL    |                | 
+-----------+-----------------------+------+-----+---------+----------------+

我希望能够获得最接近longitudelatitude坐标的邮政编码。

2 个答案:

答案 0 :(得分:1)

这是我发现的一个查询,似乎有效。

SELECT zip, city, state, ((
    ACOS(SIN(-094.076163 * PI() / 180) * 
    SIN(latitude * PI() / 180) + 
    COS(-094.076163 * PI() / 180) * 
    COS(latitude * PI() / 180) * 
    COS((44.661216 - longitude) * PI() / 180)) * 180 / PI()
) * 60 * 1.1515) AS `distance` FROM zipcodes ORDER BY `distance` limit 1;

答案 1 :(得分:1)

根据您的表格,您需要计算给定纬度和经度与每个邮政编码的纬度和经度之间的距离,然后选择最小值。

(显然,找到“最接近”的邮政编码并不意味着给定的点实际上在邮政编码边界内。)

下面的查询有一个“大圆距离”计算的实现,但这将是一个昂贵的操作,因为将对zipcodes表中的每一行执行此计算:

SELECT ACOS( COS(RADIANS( d2.latitude ))
           * COS(RADIANS( d1.latitude ))
           * COS(RADIANS( d2.longitude ) - RADIANS( d1.longitude ))
           + SIN(RADIANS( d2.latitude ))
           * SIN(RADIANS( d1.latitude ))
           ) * 3958.82 AS distance_miles
     , d2.*
  FROM zipcodes d2
  JOIN (SELECT 44.9800 AS latitude, -93.2636 AS longitude) d1
 ORDER BY distance_miles DESC
 LIMIT 10