MBR包含距离位置的距离帮助MySQL

时间:2015-02-08 18:29:27

标签: mysql performance optimization geospatial

好的,所以我是 MBRContains 方法的新手,无法让方法正常工作。基本上我只是想根据远离输入位置的距离来过滤列表。


我听说这种方法比进行复杂的数学计算更快。如果我错了,请纠正我。


我还没有能够完成这项工作,并且希望有人能够解释它是如何工作的以及修复此代码。

SELECT  *
FROM    listings JOIN suburbs ON listings.suburb_id = suburbs.id
WHERE   MBRContains
  (
    LineString
      (
         Point (
           @lon + 10 / ( 111.1 / COS(RADIANS(@lat))),
           @lat + 10 / 111.1
         ),
         Point (
           @lon - 10 / ( 111.1 / COS(RADIANS(@lat))),
           @lat - 10 / 111.1
         ) 
       ),
       LineString(
         Point(
           suburbs.longitude / ( 111.1 / COS(RADIANS(suburbs.latitude))),
            suburbs.latitude / 111.1
         )
      ) 
   ) 

我从另一个问题得到了这个代码,但我还是无法理解或解决它。实际上他们有,我有第二个 LIneString 。但我将 lat lng 存储在自己的列中。


我想将此代码转换为函数,比如说 WITHINDISTANCE 函数,我会调用它来代替那一大堆代码。

1 个答案:

答案 0 :(得分:1)

MBRContains()的目的是利用MySQL geospatial index。当您在自己的列中latlng时,MBRContains()根本无法提供相应的效果。

但您可以直接使用列值进行边界矩形计算。执行此操作时,可以使用BETWEEN运算符查找相应的行。该运算符在MySQL索引中运行得非常好,因为它可以进行索引范围扫描。

您可以像这样使用SQL。

@lat := --the latitude of your point;
@lng := --the longitude of your point;
@radius := 10;
@distance_unit = 111.1;

WHERE suburbs.latitude
     BETWEEN @lat  - (@radius / @distance_unit)
         AND @lat  + (@radius / @distance_unit)
AND suburbs.longitude
 BETWEEN @lng - (@radius / (@distance_unit * COS(RADIANS(@lat))))
     AND @lng + (@radius / (@distance_unit * COS(RADIANS(@lat))))

它看起来很乱,但它会进行简单的边界框计算,然后在纬度和经度列上进行索引扫描。

以下是如何执行此操作的完整说明。 http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/