根据纬度/经度在20公里范围内选择

时间:2011-08-02 22:50:43

标签: php mysql select

我有一个根据以下示例构建的mysql表:

POSTAL_CODE_ID|PostalCode|City|Province|ProvinceCode|CityType|Latitude|Longitude
7|A0N 2J0|Ramea|Newfoundland|NL|D|48.625599999999999|-58.9758
8|A0N 2K0|Francois|Newfoundland|NL|D|48.625599999999999|-58.9758
9|A0N 2L0|Grey River|Newfoundland|NL|D|48.625599999999999|-58.9758

现在我要做的是创建一个查询,选择搜索位置选定公里范围内的结果

所以我们说他们搜索“灰河”并选择“查找20公里内的所有结果”

显然应选择“灰河”,但也应根据纬度和经度选择灰河20公里范围内的所有地点。

我真的不知道该怎么做。我已经阅读了关于hasrsine公式,但不知道如何将它应用于mysql SELECT。

任何帮助都会非常感激。

4 个答案:

答案 0 :(得分:9)

SELECT  *
FROM    mytable m
JOIN    mytable mn
ON      ACOS(COS(RADIANS(m.latitude)) * COS(RADIANS(mn.latitude)) * COS(RADIANS(mn.longitude) - RADIANS(m.longitude)) + SIN(RADIANS(m.latitude)) * SIN(radians(mn.latitude))) <= 20 / 6371.0
WHERE   m.name = 'grey river'

如果您的表格为MyISAM,您可能希望以原生几何格式存储积分并在其上创建SPATIAL索引:

ALTER TABLE mytable ADD position POINT;

UPDATE  mytable
SET     position = POINT(latitude, longitude);

ALTER TABLE mytable MODIFY position NOT NULL;

CREATE SPATIAL INDEX sx_mytable_position ON mytable (position);

SELECT  *
FROM    mytable m
JOIN    mytable mn
ON      MBRContains
                (
                LineString
                        (
                        Point
                                (
                                X(m.position) - 0.009 * 20,
                                Y(m.position) - 0.009 * 20 / COS(RADIANS(X(m.position)))
                                ),
                        Point
                                (
                                X(m.position) + 0.009 * 20,
                                Y(m.position) + 0.009 * 20 / COS(RADIANS(X(m.position))
                                )
                        ),
                mn.position
                )
        AND ACOS(COS(RADIANS(m.latitude)) * COS(RADIANS(mn.latitude)) * COS(RADIANS(mn.longitude) - RADIANS(m.longitude)) + SIN(RADIANS(m.latitude)) * SIN(radians(mn.latitude))) <= 20 / 6371.0
WHERE   m.name = 'grey river'

答案 1 :(得分:1)

SELECT `s`.suburb_id,`s`.suburb_name,`s`.lat,`s`.long, (((acos(sin(($lat*pi()/180)) * sin((s.lat*pi()/180))+cos(($lat*pi()/180)) * cos((s.lat*pi()/180)) * cos((($long - s.long)*pi()/180))))*180/pi())*60*1.1515*1.609344) AS distance FROM (`mst_suburbs` as s) HAVING distance <= 20 ORDER BY `s`.suburb_id DESC

此查询适用于我获取12公里距离之间的所有纬度。我mst_suburbs可以列出latlong列。{{1} }和$lat是我的两个php变量。我传递了所需的lat,很长,以便从$long得到最近的12km纬度长列表。您只需根据您的表更改列的名称并传递lat,以便查询。

答案 2 :(得分:0)

这是一个有点复杂的算法,但是here's a link to one solution

答案 3 :(得分:0)

您只需使用您的半身定制公式并将其应用于此:

SELECT   *,
         6371 * ACOS(SIN(RADIANS( $lat1 )) * SIN(RADIANS(`Latitude`)) +
         COS(RADIANS( $lat1 )) * COS(RADIANS(`Latitude`)) * COS(RADIANS(`Longitude`) -
         RADIANS( $lon1 ))) AS `distance`
FROM     `table`
WHERE    `distance` <= 20
ORDER BY `distance` ASC

$lat1$lon1替换为您要比较的纬度和经度。

相关问题