因为应用是基于MySql的,所以我们的技术选型也是主要有两种:一种是多边形是否包含,一种是对每一个点进行计算。

首先看第一种:区域内搜索

在我们的业务平台中有很多景区的,每个景区都有围栏地址和中心点地址,我从中摘录一部分,这次重点关注fence_center也就是中心点字段。
我们的table定义如下:

CREATE TABLE `map` (
 `id` int(11) NOT NULL,
 `name` varchar(32) COLLATE utf8_unicode_ci NOT NULL COMMENT '景区名称',
 `fence_center` point DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='景区表';

我先确定一个多边形围栏,然后直接查找在围栏内的点。这样的计算有一个问题,就是必须事先知道多边形区域,这种方式更适合按区域查找场景。

SELECT * FROM map 
WHERE MBRCONTAINS( ST_GEOMFROMTEXT( 'POLYGON((117.152946 36.695436,
117.155092 36.669693,117.124794 36.661913,
117.110632 36.697707,117.152946 36.695436))' ), 
fence_center )

我们在地图上画出来的围栏和中心点,黄色线框覆盖就是围栏区域,蓝色气泡就是中心点。

再看第二种:基于半径距离的搜索

首先需要明白的几个函数
ST_Distance、Distance 这两个函数完全一样只是名字不同,推荐使用ST_Distance。函数返回两个参数点之间的距离,如果其中一个参数是null或者空的geomrtry,则返回null。
下面我们看一个例子:

mysql> SET @g1 = Point(1,1);
mysql> SET @g2 = Point(2,2);
mysql> SELECT ST_Distance(@g1, @g2);
+-----------------------+
| ST_Distance(@g1, @g2) |
+-----------------------+
|    1.4142135623730951 |
+-----------------------+

ST_Distance_Sphere 为MySQL 5.7的GIS特性,定义如下:ST_Distance_Sphere(g1, g2 [, radius]) 和ST_Distance相比,该函数可支持基于球形的距离计算,默认的半径参数是6370986,
做GIS开发的同学应该对这个数值很熟悉了,没错就是地球半径。这样我们就能精准的计算低于GPS的点距离。
下面看一下用法示例:

mysql> SET @pt1 = ST_GeomFromText('POINT(0 0)');
mysql> SET @pt2 = ST_GeomFromText('POINT(180 0)');
mysql> SELECT ST_Distance_Sphere(@pt1, @pt2);
+--------------------------------+
| ST_Distance_Sphere(@pt1, @pt2) |
+--------------------------------+
|             20015042.813723423 |
+--------------------------------+

下一步我们要基于一个位置,查询该位置1千米半径内所有点。
table定义还是和上面一样。先找到中心点,然后通过ST_Distance_sphere计算两个之间的地理距离,然后直接比较计算结果,满足条件的直接返回。

下面是我的精简的SQL语句:

SET @pt2 = ST_GeoFromText('POINT(117.338355 36.183116)');  
SELECT *, ST_DISTANCE_SPHERE(fence_center, @pt2) AS point_distance 
FROM map WHERE ST_DISTANCE_SPHERE(fence_center, @pt2) < 10000

Tags: mysql poi, 按距离范围查找, 按区域查找

Related Posts:
  • [尚无相关文章]

Leave a Comment