为表格中的每一行选择最近的点

时间:2018-05-06 11:27:48

标签: mysql geospatial openstreetmap

我用它来找到最近的点

let postID = // set id
Database.database().reference().child("Posts").child("\(postID)").removeValue()

我有一个带有所有候选点的临时表TempPoints,我想将它们规范化到OSM节点上,但是有很多,所以我需要一个查询来在一次调用中解决它们。 UNION不会让我使用order by,而我的DB raw查询界面不会让我发出一系列由';'分隔的查询。 临时表有lat和lon但可以很容易地有一个POINT。我怎么去

SELECT 
  id, 
  ST_Distance(
   POINT(52.760667210533,-7.22646337599035),
   geo_point
  ) as distance 
from Points 
order by distance limit 1

编辑:我可以在我的大型联合查询中对每个选择进行括号,这解决了我的问题。

我仍然希望能够加入最近的行。

2 个答案:

答案 0 :(得分:0)

这可能对您有用:

SELECT t.id as tid, p.id as pid, p.geo_point
FROM TempPoint t
JOIN Points p ON p.id = (
    SELECT p1.id
    FROM Points p1
    ORDER BY ST_Distance(p1.geo_point, t.geo_point)
    LIMIT 1
)

答案 1 :(得分:0)

我的解决方案是发出一系列查询,每行一个查询,并使用UNION将它们绑定在一起。 mysql堆栈最终会爆炸,所以你需要在块中执行它们,但在默认安装中1000可以。 您必须将查询括起来,因为它们包含订单。某些点可能会失败,因此我使用文字line_no序列标记它们,以便您可以编辑和过滤原件。您还需要使用

限制查询
WHERE Contains(<polygon>,point) 

子句,否则它将尝试对整个表进行排序,其中多边形是一个必须使用GEOMFROMTEXT()和POLYGON()进行烹饪的边界框。当然,你需要在列上有一个特殊的空间索引!这是一些代码

            var SMALL=0.001

            var=query=points
                .map(function(point){
                    var bottom=point.lat+SMALL
                    var top=point.lat-SMALL
                    var left=point.lon-SMALL
                    var right=point.lon+SMALL
                    var polygon=[
                        [bottom,left],
                        [top,left],
                        [top,right],
                        [bottom,right],
                        [bottom,left]
                    ]
                    polygon="POLYGON(("+polygon.map(function(point){
                        return point.join(' ')
                    })
                    .join(",")+"))"

                    point.line_no=line_no++
                    return "(SELECT "+point.line_no+" as line_no,id, ST_Distance(POINT("+
                                point.lat+","+point.lon+
                                "),geo_point) as distance"+
                                " from Points "+
                                " WHERE Contains(GeomFromText('"+polygon+"'),geo_point) "+
                                " order by distance limit 1) "
                })
                .join(" UNION ")+" order by line_no"
            return sequelize.query(query)