使用边界圆与geosearch的距离不准确

时间:2014-01-27 21:09:54

标签: php mysql geolocation latitude-longitude

我一直在尝试不同的方法来加速网站上的位置搜索,我一直在接受http://www.movable-type.co.uk/scripts/latlong-db.html的说明。

代码已根据我的表量身定制并输入变量,因此我可以通过phpmyadmin运行它

Select id, outcode, lat, lng, acos(sin(57.101)*sin(radians(lat)) + 
cos(57.101)*cos(radians(lat))*cos(radians(lng)-'-2.27')) * 3959 As D
From 
  (Select id, outcode, lat, lng
   From car_postcodes
    WHERE
    lat Between 52.7593142577 And 61.4426857423
    And 
    lng Between -10.2633856968 And 5.72338569684
    ) As FirstCut 
Where acos(sin(57.101)*sin(radians(lat)) + 
cos(57.101)*cos(radians(lat))*cos(radians(lng)-'-2.27)) * 3959 < 7000
Order by D

问题是搜索结果显示距离该位置5448(英里?)的最小距离,这是不正确的,因为所有邮政编码都在英国境内。 (因此'&lt; 7000)

这是查找最小/最大经度和数字的代码。纬度:

$lat = 57.101;  // latitude of centre of bounding circle in degrees
$lon = -2.27;  // longitude of centre of bounding circle in degrees
$rad = 300;  // radius of bounding circle in kilometers

$R = 3959;  // earth's mean radius, m

// first-cut bounding box (in degrees)
$maxLat = $lat + rad2deg($rad/$R);
$minLat = $lat - rad2deg($rad/$R);
// compensate for degrees longitude getting smaller with increasing latitude
$maxLon = $lon + rad2deg($rad/$R/cos(deg2rad($lat)));
$minLon = $lon - rad2deg($rad/$R/cos(deg2rad($lat)));

前三项结果显示:

 ID     postcode      lat      lng      D      
 1143   HS2           58.249   -6.468   5428.525603021315 
 1142   HS1           58.213   -6.381   5432.53243648885
 1144   HS3           57.879   -6.853   5435.933627885293

lng&amp;表中的lat列存储为二进制并被索引。

非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

您可以使用:start_lat:start_lng:min_distance:max_distance运行此操作,d以英里为单位。我的代码中没有速度问题,但让我知道它是如何运行的。

SELECT SQL_CALC_FOUND_ROWS
                *
                FROM (SELECT id, outcode, lat, lng, ( 3959*(2*ASIN(SQRT(POW(SIN(((car_postcodes.lat-:start_lat)*(PI()/180))/2),2)+COS(car_postcodes.lat*0.017453293)*COS(:start_lat*0.017453293)*POW(SIN(((car_postcodes.lng-:start_lgn)*(PI()/180))/2),2)))) ) AS d
                    FROM car_postcodes
                WHERE 1) AS tmp_tbl
            WHERE d <= :max_distance AND d >= :min_distance
            ORDER BY d ASC