从点 Table 中找到 MySQL 最近的点
Find nearest points with MySQL from points Table
我有一个DB Schema like this (from this tutorial by Google) -
所以他们在图表中的实际点是这样的-
我想要的是找到给定点附近的点(按point_id)点按距离排序
Location of a point (x,y)
is (point_x
,point_y
) in DB
我想用MySQL解决,因为我的数据库已经在MySQL.
更新-
求2个点的距离就是这么简单-
我想用 MySQL 按距离排序。
重新
为了消除混淆,我稍后要圆圈内的点。但是现在我只想找到排序的点。
所以你可以忽略圆圈。
我不知道该怎么做,有人可以帮忙吗?
请尝试此查询[一种直接的方法]:
假设,您想要找到具有 point_id = 5
的点最近的 20 个点
SET @givent_point_id := 5;
SELECT
P1.point_id,
P1.point_name,
P1.point_x,
P1.point_y,
(POW(ABS((P2.point_x - P1.point_x)),2) + POW(ABS((P2.point_y - P1.point_y)),2)) AS sqr_distance
FROM Point P1,
(SELECT point_x,point_y FROM Point WHERE point_id = @givent_point_id) P2
WHERE P1.point_id <> @givent_point_id
ORDER BY sqr_distance
LIMIT 20;
更多:你可以看看MySQL SPATIAL DATATYPE。
MySQL空间索引使用R-tree
作为数据结构,专为空间访问方法设计。
R-trees are tree data structures used for spatial access methods,
i.e., for indexing multi-dimensional information such as geographical
coordinates, rectangles or polygons.
我找到了比@1000111 的解决方案更好的解决方案。
MySQL 中有针对此类数据的自定义数据库类型,可提供更好的性能。
OpenGIS in MySQL 非常适合这个。
给出函数here.
this Whosebug question.
中给出了说明性定义
我的解决方案是这样的-
DB Table-
CREATE TABLE geoTable
(
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL,
geoPoint POINT NOT NULL,
SPATIAL INDEX(geoPoint)
) ENGINE=MyISAM;
INSERT INTO geoTable (name, geoPoint)
VALUES
( "A", GeomFromText('POINT(0.1 -1.01)') ),
( "B", ST_GeomFromText('POINT(56.31 2.81)') ),
( "C", ST_GeomFromText('POINT(11.1 1.176)') ),
( "ui", ST_GeomFromText('POINT(9.1 2.1)') );
SQL查询-
SELECT
id,
name,
X(geoPoint) AS "latitude",
Y(geoPoint) AS "longitude",
(
GLength(
LineStringFromWKB(
LineString(
geoPoint,
GeomFromText('POINT(51.5177 -0.0968)')
)
)
)
)
AS distance
FROM geoTable
ORDER BY distance ASC;
举个例子SQL Fiddle here.
看执行时间-
150个条目,仅需13ms。
我有一个DB Schema like this (from this tutorial by Google) -
所以他们在图表中的实际点是这样的-
我想要的是找到给定点附近的点(按point_id)点按距离排序
Location of a point
(x,y)
is (point_x
,point_y
) in DB
我想用MySQL解决,因为我的数据库已经在MySQL.
更新-
求2个点的距离就是这么简单-
我想用 MySQL 按距离排序。
重新
为了消除混淆,我稍后要圆圈内的点。但是现在我只想找到排序的点。
所以你可以忽略圆圈。
我不知道该怎么做,有人可以帮忙吗?
请尝试此查询[一种直接的方法]:
假设,您想要找到具有 point_id = 5
SET @givent_point_id := 5;
SELECT
P1.point_id,
P1.point_name,
P1.point_x,
P1.point_y,
(POW(ABS((P2.point_x - P1.point_x)),2) + POW(ABS((P2.point_y - P1.point_y)),2)) AS sqr_distance
FROM Point P1,
(SELECT point_x,point_y FROM Point WHERE point_id = @givent_point_id) P2
WHERE P1.point_id <> @givent_point_id
ORDER BY sqr_distance
LIMIT 20;
更多:你可以看看MySQL SPATIAL DATATYPE。
MySQL空间索引使用R-tree
作为数据结构,专为空间访问方法设计。
R-trees are tree data structures used for spatial access methods, i.e., for indexing multi-dimensional information such as geographical coordinates, rectangles or polygons.
我找到了比@1000111 的解决方案更好的解决方案。
MySQL 中有针对此类数据的自定义数据库类型,可提供更好的性能。
OpenGIS in MySQL 非常适合这个。
给出函数here.
this Whosebug question.
中给出了说明性定义我的解决方案是这样的-
DB Table-
CREATE TABLE geoTable
(
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL,
geoPoint POINT NOT NULL,
SPATIAL INDEX(geoPoint)
) ENGINE=MyISAM;
INSERT INTO geoTable (name, geoPoint)
VALUES
( "A", GeomFromText('POINT(0.1 -1.01)') ),
( "B", ST_GeomFromText('POINT(56.31 2.81)') ),
( "C", ST_GeomFromText('POINT(11.1 1.176)') ),
( "ui", ST_GeomFromText('POINT(9.1 2.1)') );
SQL查询-
SELECT
id,
name,
X(geoPoint) AS "latitude",
Y(geoPoint) AS "longitude",
(
GLength(
LineStringFromWKB(
LineString(
geoPoint,
GeomFromText('POINT(51.5177 -0.0968)')
)
)
)
)
AS distance
FROM geoTable
ORDER BY distance ASC;
举个例子SQL Fiddle here.
看执行时间-
150个条目,仅需13ms。